我正在尝试做这样的事情:
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”方法吗?
答案 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];
});