1

I have a method that takes a string and a completion block argument. I only care about the string argument, but OCMockObject throws an exception, what should I pass as the block argument?

My Protocol

@protocol SomeService <NSObject>

- (void)fetchDataForUsername:(NSString *)username andCompletion:(void (^)(NSArray *someData, NSError *error))completion;

@end

My test

OCMockObject *mock = [OCMockObject niceMockForProtocol:@protocol(SomeService)];
[[mock expect] fetchDataForUsername:@"SPECIFIC_USERNAME" andCompletion:[OCMArg any]];

Error Log

**-[OCMAnyConstraint copyWithZone:]: unrecognized selector sent to instance 0xdc79750**
aryaxt
  • 76,198
  • 92
  • 293
  • 442

1 Answers1

3

I had some problems with mocking protocols as well. In the general case, OCMock is happy to handle blocks arguments:

// Foo
+ (void)blockTest
{
    [UIView animateWithDuration:10.0 animations:^{
        [[[[UIApplication sharedApplication] windows][0] rootViewController] view].alpha = 0.5;
    }];
}

// Test -- this works fine!
- (void)testBlock
{
    id viewMock = [OCMockObject mockForClass:UIView.class];
    [[viewMock expect] animateWithDuration:10.0 animations:OCMOCK_ANY];

    [Foo blockTest];
    [viewMock verify];

}

To get around issues with protocol mocking, I create a dummy class that implements the protocol (with empty methods), then mock the methods of this class and use it like any other mock object.

Ben Flynn
  • 18,524
  • 20
  • 97
  • 142
  • Aaaah, didn't realize that was the problem. Will give it a try. Thanks – aryaxt Feb 12 '14 at 17:37
  • I still don't get the problem, my protocol is inheriting form NSObject protocol which includes copyWithZone:. So i would think the mock would know about that method. Maybe OCMock ignores sub protocols? – aryaxt Feb 12 '14 at 17:45
  • 1
    The class NSObject defines `copyWithZone:` but I don't actually see it defined in the NSObject Protocol. Under normal circumstances it looks likes composed protocols should work fine (I tested my own protocols and also was able to get `zone` from NSObject). There must be an implicit assumption in the code under test that the object inherits from NSObject and is not just a strict implementation of the protocol. – Ben Flynn Feb 12 '14 at 18:19