1

我正在学习在单元测试中使用 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
4

3 回答 3

3

模拟单例是很棘手的。你可以用一些运行时魔法来做到这一点。可以借助Matt Gallagher 的 invokeSupersequent 宏来完成。基本上,您将一个类别添加到您的测试用例中,该类别将覆盖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];
}

不久前,我对这种方法进行了更详细的描述

于 2013-04-12T16:40:40.613 回答
3

这是一个简单的解决方案:

OCMockObject* _deviceMock = OCMPartialMock([UIDevice currentDevice]);

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

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

[UIDevice currentDevice].userInterfaceIdiom

代替宏

UI_USER_INTERFACE_IDIOM()
于 2015-10-08T23:47:49.080 回答
0

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

-(void)testShouldDoSomething {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        // test iPad behavior
    } else {
        // test iPhone behavior
    }
}
于 2013-04-12T16:47:02.287 回答