views:

498

answers:

3

I'm hitting a road block and I'm wondering if the brilliant collective minds here can help. In ObjC CocoaTouch I'm trying to mock an object that takes struct parameters and returns a struct. OCMock is coughing up a hair-ball so I tried wrapping with a Hamcrest matcher. No die. The function/method I'm testing looks something like this:

- (CLLocationCoordinate2D)pixelToLatLong:(CGPoint)aPoint;

I use code like this:

#define OCMOCK_STRUCT(atype, variable) [NSValue value:&variable withObjCType:@encode(atype)]
-(void) testMyWidget
{
    CLLocationCoordinate2D ulLL = (CLLocationCoordinate2D){123,456};
    CLLocationCoordinate2D lrLL = (CLLocationCoordinate2D){654,321};
    [[[(id)myObj expect] andReturn:OCMOCK_STRUCT(CLLocationCoordinate2D, ulLL)] pixelToLatLong:(CGPoint){0,0}];
    [[[(id)myObj expect] andReturn:OCMOCK_STRUCT(CLLocationCoordinate2D, lrLL)] pixelToLatLong:(CGPoint){320,460}];//lower right point
}

That kinda works. So in my object that I'm testing I make the necessary required edits to get a green bar... err.. green button in the build info window. When I'm certain that my test should pass I get assertion failed errors. The errors inform me that the method was invoked unexpectedly and lists the values for these structs as question marks. I tried wrapping the structs with Hamcrest matchers but I'm getting nowhere. I'm getting ready to break out my debugger which will no doubt show me what's wrong. Has anybody here had similar trouble with OCMock/Hamcrest and structs? If so, what's the best way to handle these types?

A: 

Sometimes a hand-coded mock is easier than trying to coerce a mock object framework outside of its normal use patterns.

Jon Reid
+1  A: 

You're very close. Your #define should be:

#define OCMOCK_STRUCT(atype, variable) [NSValue valueWithBytes:&variable withObjCType:@encode(atype)]
A: 

I had problems with the macro answer; writing a helper function that returned the struct in the testing class and using:

[[[mockObject stub] andCall:@selector(selectorName) onObject:self] someMethod];

worked really well.

Truelson