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

Posted

技术标签:

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

在我的 XCode 项目中,我有:

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

databaseController 在控制器类中实例化。

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

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

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

【问题讨论】:

我认为您的“如果 databaseController 不是单例会怎样”是一个过于模糊的问题,而不了解您的应用程序的要求。 【参考方案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。

【讨论】:

这适用于单例对象。一般来说,我仍然对模拟对象感到困惑,但我会尝试自己弄清楚。感谢您的帮助! 阅读依赖注入可能会有所帮助。模式出现的主要原因之一是人们试图使用模拟对象进行测试并遇到了您遇到的确切问题。而且,是的,答案是:不要在控制器中实例化数据库控制器,让设置使用哪个数据库控制器成为可能。

以上是关于iOS单元测试私有模拟对象?的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin Multiplatform:如何在 iOS 的单元测试中模拟对象

单元测试-PowerMock

使用宏进行 iOS 单元测试

单元测试——使用模拟对象做交互测试

在单元测试中模拟 UserDefaults 对象返回 _ArrayBuffer

springboot2.0入门----mock模拟测试+单元测试