首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用OCMock模拟[[UIDevice currentDevice] userInterfaceIdiom]

使用OCMock模拟[[UIDevice currentDevice] userInterfaceIdiom]
EN

Stack Overflow用户
提问于 2013-04-12 01:10:46
回答 3查看 1.9K关注 0票数 1

我正在学习如何在单元测试中使用OCMocks,并且我理解其中的基础知识。但是,我不确定如何模拟对类方法的调用。

我想要:

代码语言:javascript
复制
[[UIDevice currentDevice] userInterfaceIdiom]

为我的测试用例返回不同的(但有效的)接口习惯用法。

代码语言:javascript
复制
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
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-04-13 00:40:41

模仿单例是一件棘手的事情。您可以使用一些运行时魔术来完成此操作。在Matt Gallagher's invokeSupersequent macro的帮助下,这是可能的。基本上,您可以向测试用例中添加一个覆盖currentDevice以返回模拟的类别,但前提是您设置了模拟。下面是设置:

代码语言:javascript
复制
#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];
}

然后,在您的测试中:

代码语言:javascript
复制
-(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

票数 3
EN

Stack Overflow用户

发布于 2015-10-09 07:47:49

这里有一个简单的解决方案:

代码语言:javascript
复制
OCMockObject* _deviceMock = OCMPartialMock([UIDevice currentDevice]);

[[[_deviceMock stub] andReturnValue:@(UIUserInterfaceIdiomPad)] userInterfaceIdiom];

只需确保行为中的代码使用此检查

代码语言:javascript
复制
[UIDevice currentDevice].userInterfaceIdiom

而不是宏

代码语言:javascript
复制
UI_USER_INTERFACE_IDIOM()
票数 3
EN

Stack Overflow用户

发布于 2013-04-13 00:47:02

另一种方法是将这两种变体都放入您的测试中,并在iPhone和iPad模拟器中运行测试。诚然,这有点麻烦。

代码语言:javascript
复制
-(void)testShouldDoSomething {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        // test iPad behavior
    } else {
        // test iPhone behavior
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15954828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档