Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective C - Unit testing & Mocking object?

- (BOOL)coolMethod:(NSString*)str
{
     //do some stuff
     Webservice *ws = [[WebService alloc] init];
     NSString *result = [ws startSynchronous:url];
     if ([result isEqual:@"Something"])
     {
         //More calculation
         return YES;
     }
     return NO;
}

I am using OCUnit In the following method how can i mock my WebService Object, or the result to the method "startSynchronous" to be able to write an independent unit test?

Is it possible to inject some code in there to either create a mock web service or return a mock data on startSynchronous call?

like image 314
aryaxt Avatar asked Feb 03 '11 01:02

aryaxt


1 Answers

One way is to use categories and override methods you want, you can even override the init method to return a mock object:

@interface Webservice (Mock)
- (id)init;
@end

@implementation Webservice (Mock)
- (id)init
{
     //WebServiceMock is a subclass of WebService
     WebServiceMock *moc = [[WebServiceMock alloc] init];
     return (Webservice*)moc;
}
@end

The problem with this is that if you want to make the object return different results in different tests in 1 test file you cannot do that. (You can override each method once per test page)

EDIT:

This is an old question I posted, I thought I would update the answer to how I write testable code and unit test it nowadays :)

ViewController Code

@implementation MyViewController
@synthesize webService;

- (void)viewDidLoad
{
   [super viewDidLoad];

   [self.webService sendSomeMessage:@"Some_Message"];
}

- (WebService *)webService
{
   if (!_webService)
      _webService = [[WebService alloc] init];

   return _webService;
}

@end

Test Code

@implementation MyViewControllerTest

- (void)testCorrectMessageIsSentToServer
{
   MyViewController *vc = [[MyViewController alloc] init];
   vc.webService = [OCMock niceMockForClass:[WebService class]];

   [[(OCMockObject *)vc.webService expect] sendSomeMessage@"Some_Message"];
   [vc view]; /* triggers viewDidLoad */
   [[(OCMockObject *)vc.webService verify];
}

@end
like image 62
aryaxt Avatar answered Sep 23 '22 01:09

aryaxt