iOS单元测试私有模拟对象?

时间:2012-06-29 13:49:28

标签: ios unit-testing singleton ocunit ocmock

在我的XCode项目中,我有:

  • 控制器
  • (Singleton)databaseController

databaseController在控制器类中实例化。

如何使用模拟对象替换此databaseController以验证控制器类的正常运行,而不依赖于实际的databaseController?

注释:
- OCUnit用于单元测试 - OCMock用于创建Mock对象。

奖金问题:如果databaseController不是单例,该怎么办?

1 个答案:

答案 0 :(得分:2)

这是我一直采取的方法。在你的单身人士中:

static SomeManager *_sharedInstance = nil;

+(SomeManager *)sharedInstance {
    if (_sharedInstance == nil) {
        _sharedInstance = [[SomeManager alloc] init];
    }
    return _sharedInstance;
}

+(void)setSharedInstance:(SomeManager *)instance {
    _sharedInstance = instance;
}

然后,在你的测试中:

-(void)testSomethingThatUsesSingleton {
    id mockManager = [OCMockObject mockForClass:[SomeManager class]];
    [SomeManager setSharedInstance:mockManager];
    [[mockManager expect] something];

    [controller doSomething];

    [mockManager verify];
    [SomeManager setSharedInstance:nil];
}

不要忘记在测试结束时将单例设置为nil。我通常在我的单元测试基类中的tearDown中执行此操作,因此它会在每次测试后自动发生。

或者,您可以create a category in your unit tests that overrides sharedInstance to return a mock object