OCMock mock protocol static class method.
New in OCMock 3 is the ability to deflate class methods .
Is it okay to mock class methods defined in the protocol? i.e
@protocol AViewControllerProtocol <NSObject>
+ (Type)typeForViewController;
@end
Inside my class unit test
- (void)testProtocolClassMethod {
id mockedViewController = OCMProtocolMock(@protocol(AViewControllerProtocol));
//This line compiles fine, but throws an exception at run time.
OCMStub([mockedViewController typeForViewController]).andReturn(SomeType);
}
Throwing Exceptions
NSInvalidArgumentException: cannot stub / expect / check method 'typeForViewController' because no such method exists in the class class
+3
source to share
1 answer
It looks like it was an oversight in OCMock 3.1, but you can make the fix yourself if you like.
// OCProtocolMockObject.m
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
struct objc_method_description methodDescription = protocol_getMethodDescription(mockedProtocol, aSelector, YES, YES);
if(methodDescription.name == NULL)
{
methodDescription = protocol_getMethodDescription(mockedProtocol, aSelector, NO, YES);
}
// Add this case for required class methods
if (methodDescription.name == NULL)
{
methodDescription = protocol_getMethodDescription(mockedProtocol, aSelector, YES, NO);
}
// Add this case for optional class methods
if (methodDescription.name == NULL)
{
methodDescription = protocol_getMethodDescription(mockedProtocol, aSelector, NO, NO);
}
if(methodDescription.name == NULL)
{
return nil;
}
return [NSMethodSignature signatureWithObjCTypes:methodDescription.types];
}
I tested this fix with this test:
- (void)testProtocolClassMethod {
id mockedViewController = OCMProtocolMock(@protocol(AViewControllerProtocol));
// FIXED: This line compiles fine, but throws an exception at run time.
OCMStub([mockedViewController typeForViewController]).andReturn(SomeType);
Type type = [mockedViewController typeForViewController];
XCTAssertEqual(type, SomeType, @"Not equal!");
OCMVerify([mockedViewController typeForViewController]);
}
I'll post a request on the project page for this.
0
source to share