1

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

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”方法吗?

4

2 回答 2

2

当你 mockForProtocol 时,mock 实际上并不符合协议,所以OCProtocolMockObject重写respondsToSelector为协议中定义的方法返回 YES。

OCMock 依赖于forwardInvocation:,当对象没有定义被调用的方法时,它由运行时调用。由于OCProtocolMockObjectimplements respondsToSelector,你不能模拟它。

如果您描述了您要实现的目标,则可能有另一种方法可以实现。

于 2012-06-19T17:12:18.800 回答
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];

});
于 2014-12-11T11:31:44.623 回答