【问题标题】:OCMock mock protocol's static class method.OCMock 模拟协议的静态类方法。
【发布时间】:2023-03-13 21:50:02
【问题描述】:

OCMock 3 的新功能是模拟class methods

是否可以模拟协议中定义的类方法?即

@protocol AViewControllerProtocol <NSObject>
+ (Type)typeForViewController;
@end

在我的单元测试类中

- (void)testProtocolClassMethod {
    id mockedViewController = OCMProtocolMock(@protocol(AViewControllerProtocol));

    //This line compiles fine, but throws an exception at run time.
    OCMStub([mockedViewController typeForViewController]).andReturn(SomeType);
}

异常抛出

NSInvalidArgumentException:无法存根/期望/验证方法“typeForViewController”,因为模拟类中不存在此类方法

【问题讨论】:

    标签: objective-c unit-testing ocmock


    【解决方案1】:

    这看起来像是 OCMock 3.1 中的一个疏忽,但如果需要,您可以自己进行修复。

    // 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];
    }
    

    我用这个测试验证了这个修复:

    - (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]);
    }
    

    我会为此在项目页面上提出请求。

    【讨论】:

    • 我还没有时间查看这个答案,但看起来很棒,谢谢。干得好。
    • 使用 OCMock 2.2.4 并遇到同样的问题。
    • 我刚刚将修复推送给 master。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多