Mocking NSObject and NSObject protocol

Discussion of the OCMock framework. If you have patches we would prefer you to send them to the mailing list, but attaching them to a topic is possible, too.

Mocking NSObject and NSObject protocol

Postby lawicko » 29 Nov 2011, 17:53

I'm on XCode Version 4.2 Build 4D199 running my tests in iPhone 5.0 simulator. This is what I'm doing:
Code: Select all
myMock = [OCMockObject mockForClass:[NSString class]];
[[myMock expect] isEqualToString:@"myString"];
[myMock isEqualToString:@"myString"];

This works fine and proves the simple things works, now let's move on the NSObject:
Code: Select all
myMock = [OCMockObject mockForClass:[NSObject class]];
[[myMock expect] copy];
[myMock copy];

Again, works fine, and fails when I remove expect. But take a look at this:
Code: Select all
myMock = [OCMockObject mockForClass:[NSObject class]];
[[myMock expect] className];
[myMock className];

This gives me a warning during compilation:
Instance method '-className' not found (return type defaults to 'id')
and results in the crash:
error: testSomething (myTests) failed: *** -[NSProxy doesNotRecognizeSelector:className] called!
Any ideas why? The methods copy and className are both defined on NSObject (http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsobject_Class/Reference/Reference.html)

But let's go deeper:
Code: Select all
myMock = [OCMockObject mockForProtocol:@protocol(NSObject)];
[[myMock expect] zone];
[myMock zone];

works good, but hey, let's remove expect and see if it fails:
Code: Select all
myMock = [OCMockObject mockForProtocol:@protocol(NSObject)];
//[[myMock expect] zone];
[myMock zone];

Still passes the test!

A bit deeper:
Code: Select all
myMock = [OCMockObject mockForProtocol:@protocol(NSObject)];
[[[myMock expect] andReturn:[NSNumber numberWithBool:YES]] respondsToSelector:@selector(myMethod)];
[myMock respondsToSelector:@selector(myMethod)];
[myMock verify];

Fails the test: error: testSomething (myTests) failed: OCMockObject[NSObject]: expected method was not invoked: respondsToSelector:@selector(myMethod)


What am I doing wrong?
lawicko
 
Posts: 1
Joined: 29 Nov 2011, 17:12

Re: Mocking NSObject and NSObject protocol

Postby erik » 24 Jan 2012, 00:54

You're not doing anything wrong per se. You're just getting to the limits of what a mock object can do. At some point the mocks are also real objects and need to behave in a certain way to actually work with the runtime.

I've tried to keep this footprint as small as possible, by inheriting from NSProxy instead of NSObject for example, but there are certain core methods that the mock needs for itself. Using stub/expect etc is undefined in these few cases, which should be limited to the methods declared on NSProxy.

erik
erik
 
Posts: 86
Joined: 10 Oct 2009, 15:22
Location: Hamburg, Germany


Return to OCMock



cron