如何存根“respondsToSelector”方法

时间:2012-06-19 09:56:27

标签: iphone objective-c ios5 ocmock

我正在尝试做这样的事情:

id synchronizerDelegate = [OCMockObject mockForProtocol:@protocol(SynchronizerDelegate)];
BOOL isRespondsToSelector = NO;
[[[synchronizerDelegate stub] andReturnValue:OCMOCK_VALUE(isRespondsToSelector)] respondsToSelector:@selector(didLoadFullImage:)];
GHAssertFalse([synchronizerDelegate respondsToSelector:@selector(didLoadFullImage:)], nil);

以下是SynchronizerDelegate的定义

@protocol SynchronizerDelegate <NSObject>
- (void)didLoadFullImage:(NSData *)data;
@end

但是这个测试用例总是失败(返回值为YES)。

有人试图在之前存根“respondsToSelector”方法吗?

2 个答案:

答案 0 :(得分:2)

当你使用mockForProtocol时,模拟实际上并不符合协议,所以OCProtocolMockObject overrides respondsToSelector为协议中定义的方法返回YES。

OCMock依赖于forwardInvocation:,当对象未定义被调用的方法时,运行时调用该OCProtocolMockObject。由于respondsToSelector实现了{{1}},因此您无法嘲笑它。

如果你描述了你想要实现的目标,可能还有另一种方法可以解决它。

答案 1 :(得分:0)

这个问题很老,但实际上我找到了一种方法来测试两个代码路径(响应选择器并且不响应),当你这样做来检查系统功能时(比如iOS 8中的新本地化权限)

这是我的规范:

it(@"asks for location permission on viewDidLoad", ^{

    id locationManagerMock = OCMClassMock([CLLocationManager class]);

    if([locationManagerMock respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
        [[locationManagerMock expect] requestWhenInUseAuthorization];
    }
    else {
        [[locationManagerMock expect] startUpdatingLocation];
    }

    [sut setLocationManager:locationManagerMock];
    [sut view];

    [locationManagerMock verify];

});