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







All Articles