Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Unit Testing how to stop App Delegate from doing stuff

I have an app that I'm unit testing. Under normal use, the App Delegate sets things up, and starts things running. When I run my unit tests, however, I'd like the App Delegate to not do much, if any of this. How would I go about accomplishing this? It seems that some of that setup stuff is running while the test runner is running, and it tends to throw an exception right around the time a test is run, causing it to fail.

like image 639
s73v3r Avatar asked Nov 11 '22 14:11

s73v3r


1 Answers

You want to look into Mocks (or doubles). In general this is a way of diverting you calls when doing testing to bypass things like server calls, printing, logging...

In it's simplest form you can do this by just subclassing the object that you want to modify for your tests.

Say you have

@interface YourClass : NSObject
    @property NSString *dataFromServer;
@end

@implementation YourClass

-(void) load
{
    // Bunch of calls to the server you don't want to do while testing.
    self.dataFromServer = dataFromServerCallsYouDontWantToRun;
}

-(NSString*) getServerData
{
    return dataFromServer;
}

@end

Say you want to test getServerData,but don't want to actually run load because of calls to a database. Say you just want to hard code dataFromServer to be @"Mock".

In your UnitTest Project, inherit from YourClass and override any functions you don't want to actually run in your test.

@interface YourClassMock : YourClass

@end

@implementation YourClassMock

-(void) load
{
    NSLog(@"In Mock");
    self.dataFromServer = @"Mock";
}

@end

Now your test looks like this

- (void) testLoad
{
    YourClassMock yourClass = [[YourClassMock alloc] init];
    [yourClass load];
    STAssertEquals([yourClass getServerData], @"Mock", @"Returns mock data");
}

So you are fully testing getServerData without actually calling your complicated load method.

This is a basic, do it yourself example, but there are a lot of libraries that help speed this along, like OCMock (http://ocmock.org/). This can create mock objects for you without sub classing at all. And you should look into that. But hopefully you understand how you would use this. More info - http://nshipster.com/unit-testing/

like image 108
ansible Avatar answered Nov 15 '22 04:11

ansible