views:

146

answers:

1

Hi,

I would like to test a method that uses reverse Geocoding. What i would like to do is :

  • set the geocoder as a property of my controller

  • create the geocoder in the init method

  • call the geocoder in the method i want to test

  • replace the geocoder with a mock in my test

The problem is that the MKReverseGeocoder coordinate property is read only, i can only set it in the constructor method :

[[MKReverseGeocoder alloc] initWithCoordinate:coord]

And of course the coordinates are only available in the method i want to test..

Does anyone knows how i could mock the MKReverseGeocoder class ?

Thanks in advance, Vincent.

A: 

Check out Matt Gallagher's great article on unit testing Cocoa applications. He provides a category extension to NSObject that allows you to replace instances at test time. I've used it to do something similar. I think your test would look something like this:

#import "NSObject+SupersequentImplementation.h"

id mockGeocoder = nil;

@implementation MKReverseGeocoder (UnitTests)

- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate {
   if (mockGeocoder) {
      // make sure the mock returns the coordinate passed in
      [[[mockGeocoder stub] andReturn:coordinate] coordinate];
      return mockGeocoder;
   }
   return invokeSupersequent(coordinate);
}

@end

...

-(void) testSomething {
   mockGeocoder = [OCMockObject mockForClass:[MKReverseGeocoder class]];
   [[mockGeocoder expect] start];

   // code under test
   [myObject geocodeSomething];

   [mockGeocoder verify];
   // clean up
   mockGeocoder = nil;
}
chrispix