OCMock Partial Mock Object with Facade

Wednesday, July 9, 2014

Note: I'm using OCMock 3.0.2 and Xcode 5.1.1.

I've got an object that operates as a Facade for another object it owns. The way I structured it was to create a Protocol in the owned object for the methods I wanted exposed:

@protocol SyncEngineProtocol <NSObject>
- (void) updateAllGroups;

... more methods....

@interface CoreDataSyncEngine : NSObject <SyncEngineProtocol>

Then in the Facade, I create a category that conforms to this protocol, but I don't implement the category. Instead, I forward those calls to the owned object:

@interface ModelManager (SyncMethods) <SyncEngineProtocol>

@implementation ModelManager
- (id) forwardingTargetForSelector:(SEL)aSelector{
if ([_syncEngine respondsToSelector:aSelector]){
return _syncEngine;
return nil;

I'm having two problems, and I don't know if they're related:

  1. The main problem I'm having is when a Protocol method is called on the owning object (ModelManager), OCMock throws an unrecognized selector exception.

  2. The second problem I'm having is every time I run my tests, I get several exceptions thrown in the OCMock framework when I attempt to create a class mock of the Sync Engine, which pauses the code execution. I can continue through them and everything "seems" to work properly but obviously something is wrong. This is a stack trace of the exception:

0 0x00000001020c2973 in objc_exception_throw ()
5 0x0000000102352ead in +[NSMethodSignature signatureWithObjCTypes:] ()
6 0x000000010dc128ac in +[NSObject(OCMAdditions) instanceMethodForwarderForSelector:] at /tmp/ocmock.13557/Source/Source/OCMock/NSObject+OCMAdditions.m:29
7 0x000000010dc11fbb in -[OCClassMockObject setupForwarderForClassMethodSelector:] at /tmp/ocmock.13557/Source/Source/OCMock/OCClassMockObject.m:110
8 0x000000010dc1292e in +[NSObject(OCMAdditions) enumerateMethodsInClass:usingBlock:] at /tmp/ocmock.13557/Source/Source/OCMock/NSObject+OCMAdditions.m:48
9 0x000000010dc11e63 in -[OCClassMockObject prepareClassForClassMethodMocking] at /tmp/ocmock.13557/Source/Source/OCMock/OCClassMockObject.m:97
10 0x000000010dc11b5b in -[OCClassMockObject initWithClass:] at /tmp/ocmock.13557/Source/Source/OCMock/OCClassMockObject.m:31
11 0x000000010dc1316f in +[OCMockObject mockForClass:] at /tmp/ocmock.13557/Source/Source/OCMock/OCMockObject.m:48
12 0x000000010dc13231 in +[OCMockObject niceMockForClass:] at /tmp/ocmock.13557/Source/Source/OCMock/OCMockObject.m:64
13 0x000000010dc06abb in +[CSGroupControllerTests setUp] at /Users/aaron/Dropbox/Client Projects/CrowdSporting/Codebase/crowdsportingTests/CSGroupControllerTests.m:56
14 0x000000010dee148b in -[XCTestSuite performTest:] ()
15 0x000000010dee2a75 in -[XCTest run] ()
16 0x000000010dee14df in -[XCTestSuite performTest:] ()
17 0x000000010dee2a75 in -[XCTest run] ()
18 0x000000010dee14df in -[XCTestSuite performTest:] ()
19 0x000000010dee2a75 in -[XCTest run] ()
20 0x000000010dee41b4 in +[XCTestProbe runTests:] ()
27 0x0000000100b52e33 in UIApplicationMain ()

I don't think the two are related, but since I'm having the problems at the same time, I can't ignore the timing.

Any help would be appreciated.