OCMock会在测试代码中自动使用模拟实例吗?

时间:2016-05-31 15:15:11

标签: ios objective-c unit-testing ocmock

我是OCMock的新人。

我使用dispatch_once()创建了单例类MyManager

@implementation MyManager

+ (id)sharedInstance {
    static MyManager *sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
    });
    return sharedMyManager;
}

我在School类中有一个使用上述单例的方法:

@implementation School
...
- (void) createLecture {
  MyManager *mgr = [MyManager sharedInstance];
  [mgr checkLectures];
  ...
}
@end

现在,我想对这个方法进行单元测试,我使用MyManager的部分模拟:

- (void) testCreateLecture {
  // create a partially mocked instance of MyManager
  id partialMockMgr = [OCMockObject partialMockForObject:[MyManager sharedInstance]];

  // run method to test
  [schoolToTest createLecture];
  ...
}

我注意到在使用OCMock之后,在创建了我的单例MyManager实例的部分模拟后,当运行我的测试方法时,自动使用部分模拟的实例。

这对我来说有点奇怪,因为在上面的测试用例中,我只创建了MyManager实例的部分模拟而没有将其注入MyManager类,

在测试代码中调用[MyManager sharedInstance]时,OCMock如何自动强制测试中的代码使用此模拟实例?有人可以向我解释一下吗?

2 个答案:

答案 0 :(得分:3)

partialMockForObject嘲笑你传递给它的对象。

在这种情况下,您正在模拟单例(共享)对象。你不需要注入任何东西,因为sharedInstance总是返回相同的对象,现在被模拟了。它仍然是相同的参考。

想象一下,部分模拟是传递对象的简单变形,它不会创建新实例,因此您不必在这种特定情况下注入它。

答案 1 :(得分:2)

部分模拟非常酷。在幕后,OCMock对您正在模拟的类进行子类化,并且在部分模拟子类中更新您存根的任何方法。因此,对模拟类的所有引用现在将默认为子类(模拟实现)而不是超类(您的实现)。这也是一个很好的explanation in the reference