【问题标题】:iOS Unit testing private mock objects?iOS单元测试私有模拟对象?
【发布时间】:2012-06-29 13:49:28
【问题描述】:

在我的 XCode 项目中,我有:

  • 控制器
  • (单例)数据库控制器

databaseController 在控制器类中实例化。

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

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

额外问题:如果 databaseController 不是单例怎么办?

【问题讨论】:

  • 我认为您的“如果 databaseController 不是单例会怎样”是一个过于模糊的问题,而不了解您的应用程序的要求。

标签: ios unit-testing singleton ocunit ocmock


【解决方案1】:

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

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];
}

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

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

【讨论】:

  • 这适用于单例对象。一般来说,我仍然对模拟对象感到困惑,但我会尝试自己弄清楚。感谢您的帮助!
  • 阅读依赖注入可能会有所帮助。模式出现的主要原因之一是人们试图使用模拟对象进行测试并遇到了您遇到的确切问题。而且,是的,答案是:不要在控制器中实例化数据库控制器,让设置使用哪个数据库控制器成为可能。
猜你喜欢
  • 1970-01-01
  • 2016-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-07
  • 1970-01-01
  • 2020-02-07
  • 2011-05-16
相关资源
最近更新 更多