Why isn't +setup in my testcases being called when I create a custom test suite with XCTest? - xctest

I have a subclass of XCTestSuite that I instantiate and populate with tests on the fly:
+ (XCTestSuite *)defaultTestSuite {
MySuite *suite = [[MySuite alloc] initWithName:#"suite"];
[suite addTest:[[MyTestCase alloc] initWithSelector:#selector(firstTest)]];
[suite addTest:[[MyTestCase alloc] initWithSelector:#selector(secondTest)]];
return suite;
}
+ (void)setUp {}
- (void)setUp {}
- (void)firstTest {}
- (void)secondTest {}
The -(void)setUp is being called for each test, but +(void)setUp is never called. If I don't use my custom testSuite or I call:
+ (XCTestSuite *)defaultTestSuite {
XCTestSuite *suite = [super defaultTestSuite];
[suite addTest:[[MyTestCase alloc] initWithSelector:#selector(firstTest)]];
[suite addTest:[[MyTestCase alloc] initWithSelector:#selector(secondTest)]];
it does get called. Why is this?

XCTest has a private internal class called XCTestCaseSuite that is a subclass of XCTestSuite. You can see the Swift source here. It is what is responsible for calling +(void)setUp for you. If you want this same functionality, you will have to duplicate it in your custom XCTestSuite subclass. I couldn't find documentation for this anywhere, but it does make some sense in that if test cases are coming from different classes, how do you order when the +(void)setUp/+(void)tearDown methods are called.

Related

Objective C Singleton - Prevent Allocating Memeory More than Once

I use a sinlgeton in my application for managing data that is available to the whole application, which accessed via:
static MMProductManager *sharedInstance = nil;
+(MMProductManager*)SharedInstance {
dispatch_once( &resultsToken, ^(void) {
if ( ! sharedInstance ) {
sharedInstance = [[MMProductManager alloc] init];
}
});
return sharedInstance;
}
Everything is working as expected.
In Objective C, there does not seem to be a way to hide any object's init method, and in my case having more than instance of MMProductManager would lead to data being duplicated (in the best case scenario).
What I would like to do is guard against instantiating more than one instance. Other languages seem to have this feature; i.e. marking certain methods/classes as private. I am thinking of implementing something along like:
-(id)init {
// guard against instantiating a more than one instance
if ( sharedInstance )
return sharedInstance;
if ( (self = [super init]) ) {
self->_resultsQueue = dispatch_queue_create( kMMResultQLAbel, NULL );
self->_initialized = FALSE;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleNotification:)
name:UIApplicationDidReceiveMemoryWarningNotification
object:0];
[self initialize];
}
return self;
}
Does this approach seem reasonable?
What would happen in the case of someone allocating this class, then calling the init described above? Would it be reasonable to override +(id)alloc? If so How would I go about doing that?
I know the convention of exposing a SharedInstance method is an implicit message to other developers to go through this method, but I would like a bit more control if possible.
You don't want to override - init (if not for some other reason) - - init is not the method that creates the instance. You want to override + alloc for this:
#implementation SingletonClass
+ (id)alloc
{
static id instance = nil;
if (instance == nil) {
instance = [super alloc];
}
return instance;
}
#end
This way you can actually prevent (almost) completely creating multiple instances of SingletonClass.
(Unless somebody falls back to calling
id trickyDifferentInstance = class_createInstance(objc_getClass("SingletonClass"), 0));
but that's very unlikely.)

Why is my NSDate mock resulting in failed calls to [NSProxy methodSignatureForSelector:]?

I'm trying to establish a pattern where I mock class methods of objects I don't own by creating a "fake" version of the class, then swizzling the orignal version to call the "fake" version's class methods and having the fake class call instance methods on a shared object which is itself mocked.
For example:
#interface FakeNSURLConnection : NSURLConnection
+ (void)enableMock:(id)mock;
+ (void)disableMock;
- (NSURLConnection *)connectionWithRequest:(NSURLRequest *)request delegate:(id<NSURLConnectionDelegate>)delegate;
- (BOOL)canHandleRequest:(NSURLRequest *)request;
#end
#implementation FakeNSURLConnection
...
+ (NSURLConnection *)connectionWithRequest:(NSURLRequest *)request delegate:(id<NSURLConnectionDelegate>)delegate {
return [FakeNSURLConnection.sharedInstance connectionWithRequest:request delegate:delegate];
}
- (NSURLConnection *)connectionWithRequest:(NSURLRequest *)request delegate:(id<NSURLConnectionDelegate>)delegate { return nil; }
+ (BOOL)canHandleRequest:(NSURLRequest *)request { return [FakeNSURLConnection.sharedInstance canHandleRequest:request]; }
- (BOOL)canHandleRequest:(NSURLRequest *)request { return NO; }
#end
What happens is that my enable mock swaps the class methods of NSURLConnection and FakeNSURLConnection and make the "sharedInstance" a mock of FakeNSURLConnection. In this way, when my mock is enabled a call like [NSURLConnection canHandleRequest:request] will be directed to my mock method.
This gets a little trickier with NSDate, I think because it is an "abstract" class that does toll-free bridging, but I'm not sure. I thought I could get maximum benefit out of this model by having my Fake class return real values if I wanted to partially mock an object. So we have something like this:
#interface FakeNSDate : NSDate
...
- (id)date;
- (id)dateWithTimeInterval:(NSTimeInterval)seconds sinceDate:(NSDate *)date;
- (id)dateWithTimeIntervalSince1970:(NSTimeInterval)seconds;
- (id)dateWithTimeIntervalSinceNow:(NSTimeInterval)seconds;
- (id)dateWithTimeIntervalSinceReferenceDate:(NSTimeInterval)seconds;
- (id)distantFuture;
- (id)distantPast;
- (NSTimeInterval)timeIntervalSinceReferenceDate;
#end
#implementation FakeNSDate
...
+ (id)date { return [FakeNSDate.sharedInstance date]; }
- (id)date { return [[NSDate alloc] init]; }
...
#end
Not that I am not swizzling alloc, in fact I'm only swizzling the publicly available class methods as listed in the API for NSDate.
I'm using this code:
_baseDate = [NSDate dateWithTimeIntervalSinceNow:-1.0 * 90.0 * 60.0];
_nsDateMock = [OCMockObject partialMockForObject:[FakeNSDate sharedInstance]];
NSLog(#"_nsDateMock %#", [_nsDateMock class]);
[FakeNSDate enableMock:_nsDateMock];
[[[_nsDateMock stub] andReturn:_baseDate] date];
NSLog(#"DATE: %#", [NSDate date]);
This code executes properly (the date reports being 1.5 hours ago) but I get an error that pops up: [NSProxy methodSignatureForSelector:] called!
Is the issue something I'm doing or something that partialMockForObject does? This pattern I'm using seems very helpful -- I'd hate to think it's a dead end.
I did two things to make my problems go away:
_nsDateMock = [OCMockObject partialMockForObject:[FakeNSDate sharedInstance]];
I must not have been unsetting this correctly and, I think, re-partial-mocking and already partial-mocked object. I changed it to just alloc a new object:
_nsDateMock = [OCMockObject partialMockForObject:[[FakeNSDate alloc] init]];
I also switched to using the latest code off of github.

Singleton in iOS 5?

Hi I had an implementation previous versions of iOS for a singleton as follows:
.h file
#interface CartSingleton : NSObject
{
}
+(CartSingleton *) getSingleton;
.m file
#implementation CartSingleton
static CartSingleton *sharedSingleton = nil;
+(CartSingleton *) getSingleton
{
if (sharedSingleton !=nil)
{
NSLog(#"Cart has already been created.....");
return sharedSingleton;
}
#synchronized(self)
{
if (sharedSingleton == nil)
{
sharedSingleton = [[self alloc]init];
NSLog(#"Created a new Cart");
}
}
return sharedSingleton;
}
//==============================================================================
+(id)alloc
{
#synchronized([CartSingleton class])
{
NSLog(#"inside alloc");
NSAssert(sharedSingleton == nil, #"Attempted to allocate a second instance of a singleton.");
sharedSingleton = [super alloc];
return sharedSingleton;
}
return nil;
}
//==============================================================================
-(id)init
{
self = [super init];
}
However on the web I see people have implemented the Singleton design pattern using this code:
+ (id)sharedInstance
{
static dispatch_once_t pred = 0;
__strong static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init]; // or some other init method
});
return _sharedObject;
}
Could someone who is experience please guide me.
Im a newbie and thoroughly confused between the old iOS implementation of the Singleton and the new one and which is the correct one?
Thanks a lot
Strictly speaking, you must use:
+ (MySingleton*) instance {
static dispatch_once_t _singletonPredicate;
static MySingleton *_singleton = nil;
dispatch_once(&_singletonPredicate, ^{
_singleton = [[super allocWithZone:nil] init];
});
return _singleton;
}
+ (id) allocWithZone:(NSZone *)zone {
return [self instance];
}
Now you guarantee that one cannot call alloc/init and create another instance.
Explanation: The instance method is at the class level and is your main access method to get a reference to the singleton. The method simply uses the dispatch_once() built-in queue that will only execute a block once. How does the runtime guarantee that the block is only executed once? Using the predicate you supply (of type dispatch_once_t). This low-level call will guarantee that even if there are multiple threads trying to call it, only one succeeds, the others wait until the first one is done and then returns.
The reason we override allocWithZone is because alloc calls allocWithZone passing nil as the zone (for the default zone). To prevent rogue code from allocating and init-ializing another instance we override allocWithZone so that the instance passed back is the already initialized singleton. This prevents one from creating a second instance.
The dispatch_once snippet is functionally identical to other one. You can read about it at http://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man3/dispatch_once.3.html.
This is what I use for singletons:
+ (MySingleton*) getOne {
static MySingleton* _one = nil;
#synchronized( self ) {
if( _one == nil ) {
_one = [[ MySingleton alloc ] init ];
}
}
return _one;
}
NOTE: In most cases, you do not even need to use #synchronized (but it is safe this way).
A singleton is a special kind of class where only one instance of the class exists for the current process. (In the case of an iPhone app, the one instance is shared across the entire app.) Some examples in UIKit are [UIApplication sharedApplication] (which returns the sole instance of the application itself), and [NSFileManager defaultManager] (which returns the file manager instance). Singletons can be an easy way to share data and common methods across your entire app.
Rather than create instances of the singleton class using alloc/init, you'll call a class method that will return the singleton object. You can name the class method anything, but common practice is to call it sharedName or defaultName.
Please check a link with best answer
:http://www.idev101.com/code/Objective-C/singletons.html

init] as a factory method

I want to initialize an instance of one of the subclasses of a superclass depending on the arguments to init:
[[Vehicle alloc] initWithItinerary: shortWay]; // returns a bicycle
[[Vehicle alloc] initWithItinerary: longWay]; // returns a car
I can't find examples of code like this. I wonder if this is not idiomatic in Objective C, or I simply am not looking in the right places.
You could do this via a custom init method, but it'd be kind of tedious (you'd have to invoke [super init], but then call [self release], etc...). It'd be much simpler to create a class method on Vehicle and use that as your factory method. For example:
+ (id) vehicleWithItinerary:(id)someItinerary {
if ([someItinerary isAShortWay]) {
return [[[Bicycle alloc] initWithItinerary:someItinerary] autorelease];
} else if ([someItinerary isAMediumWay]) {
return [[[RocketPack alloc] initWithItinerary:someItinerary] autorelease];
} else if ([someItinerary isALongWay]) {
return [[[Car alloc] initWithItinerary:someItinerary] autorelease];
}
return nil;
}
Look at [UIButton buttonWithType:] for an example of how Apple does this. Instead of init, they use a static method of the base class to allocate an instance of the appropriate derived class.
You can also pass around Class objects. Maybe the itinerary knows the Class or class name to allocate. You can do something like this:
[[[itinerary classToAllocate] alloc] initWithItinerary:itinerary];
or
[[NSClassFromString( [itinerary classNameToAllocate] ) alloc] initWithItinerary:itinerary];
You are allowed to release self and create a new object in init, although this is rarely used. Just watch out for recursion.
-(id) initWithItinerary:(Itinerary *)inItinerary {
[self release]; // super init never called - safe if you wrote super classes
self = [[[inItinerary classToAllocate] alloc] init];
self.itinerary = inItinerary;
return self;
}
This is called a class cluster. Several Cocoa classes work this way, including NSArray and NSString. The object returned from NSArray's init methods is never the same object that received the message. It's not that common outside of Cocoa, though, just because it's usually more complicated than people want to bother with. Basically, you figure out what actual class you want to use in your initializer, create an instance of that class, release yourself and return the other instance.
You might want to add an enum to the header file:
typedef enum {Bike, Car, JetPack
} vehicleType
That way your initWithItinerary: method can simply be:
if(VehicleType == Bike)
{
//do bike stuff
}
else if(VehicleType == Car)
{
//do car stuff
}
Why not have a method as part of the "way" that gives you a vehicle of the appropriate type for the way. e.g.
e.g.
// Somwhere before you use them. Car and Bicycle are subclasses of Vehicle
[shortWay setAppropriateVehicleType: [Bicycle class]];
[longWay setAppropriateVehicleType: [Car class]];
// when you need a vehicle
Vehicle* vehicle = [[[shortWay appropriateVehicleType] alloc] init];

How can i unit test an object internal to a method in Objective-C?

I'm wondering how to go about testing this. I have a method that takes a parameter, and based on some properties of that parameter it creates another object and operates on it. The code looks something like this:
- (void) navigate:(NavContext *)context {
Destination * dest = [[Destination alloc] initWithContext:context];
if (context.isValid) {
[dest doSomething];
} else {
// something else
}
[dest release];
}
What i want to verify is that if context.isValid is true, that doSomething is called on dest, but i don't know how to test that (or if that's even possible) using OCMock or any other traditional testing methods since that object is created entirely within the scope of the method. Am i going about this the wrong way?
You could use OCMock, but you'd have to modify the code to either take a Destination object or to use a singleton object which you could replace with your mock object first.
The cleanest way to do this would probably be to implement a
-(void) navigate:(NavContext *)context destination:(Destination *)dest;
method. Change the implementation of -(void) navigate:(NavContext *)context to the following:
- (void) navigate:(NavContext *)context {
Destination * dest = [[Destination alloc] initWithContext:context];
[self navigate:context destination:dest];
[dest release];
}
This will allow your tests to call the method with an extra parameter directly. (In other languages, you would implement this simply by providing a default value for the destination parameter, but Objective-C does not support default parameters.)
What i want to verify is that if context.isValid is true, that doSomething is called on dest
I think you may be testing the wrong thing here. You can safely assume (I hope) that boolean statements work correctly in ObjC. Wouldn't you want to test the Context object instead? If context.isValid then you're guaranteed that the [dest doSomething] branch gets executed.
It's completely possible, using such interesting techniques as method swizzling, but it's probably going about it the wrong way. If there's absolutely no way to observe the effects of invoking doSomething from a unit test, isn't the fact that it invokes doSomething an implementation detail?
(If you were to do this test, one way to accomplish your aims would be replacing the doSomething method of Destination with one that notifies your unit test and then passes on the call to doSomething.)
I like to use factory methods in this situation.
#interface Destination(Factory)
+ (Destination *)destinationWithContext:(NavContext *)context;
#end
#implementation Destination(Factory)
+ (Destination *)destinationWithContext:(NavContext *)context
{
return [[Destination alloc] initWithContext:context];
}
#end
I then make a FakeClass:
#import "Destination+Factory.h"
#interface FakeDestination : Destination
+ (id)sharedInstance;
+ (void)setSharedInstance:(id)sharedInstance;
// Note! Instance method!
- (Destination *)destinationWithContext:(NavContext *)context;
#end
#implementation FakeDestination
+ (id)sharedInstance
{
static id _sharedInstance = nil;
if (!_sharedInstance)
{
_sharedInstance = [[FakeDestination alloc] init];
}
return _sharedInstance;
}
+ (void)setSharedInstance:(id)sharedInstance
{
_sharedInstance = sharedInstance;
}
// Overrides
+ (Destination *)destinationWithContext:(NavContext *)context { [FakeDestination.sharedInstance destinationWithContext:context]; }
// Instance
- (Destination *)destinationWithContext:(NavContext *)context { return nil; }
#end
Once you set this up, you just need to swizzle the class methods for + (Destination *)destinationWithContext:(NavContext *)context;
Now you're set to:
id destinationMock = [OCMock mockForClass:FakeDestination.class];
// do the swizzle
[FakeDestination setSharedInstance:destinationMock];
[[destinationMock expect] doSomething];
// Call your method
[destinationMock verify];
This is a fair amount of coding up front, but it's very reusable.