我正在学习如何在单元测试中使用OCMocks,并且我理解其中的基础知识。但是,我不确定如何模拟对类方法的调用。
我想要:
[[UIDevice currentDevice] userInterfaceIdiom]为我的测试用例返回不同的(但有效的)接口习惯用法。
id mock = [OCMockObject mockForClass:[UIDevice class]];
// Would I use a mock or a stub to have UIDevice mock return
// currentDevice and then from it, return userInterfaceIdiom发布于 2013-04-13 00:40:41
模仿单例是一件棘手的事情。您可以使用一些运行时魔术来完成此操作。在Matt Gallagher's invokeSupersequent macro的帮助下,这是可能的。基本上,您可以向测试用例中添加一个覆盖currentDevice以返回模拟的类别,但前提是您设置了模拟。下面是设置:
#import "NSObject+SupersequentImplementation.h"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
@implementation UIDevice (UnitTests)
+(id)currentDevice {
if ([BaseTestCase mockDevice]) {
return [BaseTestCase mockDevice];
}
return invokeSupersequentNoArgs();
}
@end
#pragma clang diagnostic pop
static id mockDevice = nil;
+(id)mockDevice {
return mockDevice;
}
+(id)createMockDevice {
mockDevice = [OCMockObject mockForClass:[UIDevice class]];
return mockDevice;
}
+(id)createNiceMockDevice {
mockDevice = [OCMockObject niceMockForClass:[UIDevice class]];
return mockDevice;
}
-(void)tearDown {
mockDevice = nil;
[super tearDown];
}然后,在您的测试中:
-(void)testShouldDoSomethingOnIpad {
id mockDevice = [BaseTestCase createNiceMockDevice];
[[[mockDevice stub] andReturnValue:OCMOCK_VALUE(UIUserInterfaceIdiomPad)] userInterfaceIdiom];
// do something iPad-specific
[mockDevice verify];
}前段时间我做了一个more detailed write-up of this approach。
发布于 2015-10-09 07:47:49
这里有一个简单的解决方案:
OCMockObject* _deviceMock = OCMPartialMock([UIDevice currentDevice]);
[[[_deviceMock stub] andReturnValue:@(UIUserInterfaceIdiomPad)] userInterfaceIdiom];只需确保行为中的代码使用此检查
[UIDevice currentDevice].userInterfaceIdiom而不是宏
UI_USER_INTERFACE_IDIOM()发布于 2013-04-13 00:47:02
另一种方法是将这两种变体都放入您的测试中,并在iPhone和iPad模拟器中运行测试。诚然,这有点麻烦。
-(void)testShouldDoSomething {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// test iPad behavior
} else {
// test iPhone behavior
}
}https://stackoverflow.com/questions/15954828
复制相似问题