OCMock - "调用了意外的方法"虽然残缺不全

时间:2014-05-24 00:56:05

标签: ios unit-testing ocmock

以下是测试代码:

id dataControllerMock = [OCMockObject mockForClass:[RAMImsakyaDataController class]];
[[[dataControllerMock expect] andReturn:dataControllerMock] alloc];
(void)[[[dataControllerMock expect] andReturn:dataControllerMock] init];
[[[dataControllerMock stub] andReturn:@"30.06 , 50.67"] getLocationTitle];
[self.viewController viewDidLoad];
XCTAssertTrue([self.viewController.title isEqualToString:@"30.06 , 50.67"], @"View controller title is wrong");
[dataControllerMock verify];

问题是dataControllerMock导致失败“调用了意外的方法:getLocationTitle”!我做了存根方法。即使我改变存根期望,同样的事情。当我在viewDidLoad中断点时,模拟已按预期存在,但它无法识别getLocationTitle方法。

更新:这是viewDidLoad代码

NSString *location = [self.dataController getLocationTitle];
if (location == nil) {
    self.title = @"إمساكية رمضان ١٤٣٥ هـ";

} else {
    self.title = [NSString stringWithFormat:@"إمساكية رمضان ١٤٣٥ هـ (توقيت %@)", location];

}

2 个答案:

答案 0 :(得分:0)

为什么不采取不同的方法并使用部分模拟?

RAMImsakyaDataController* realObject = [RAMImsakyaDataController new];
id partialObject = [OCMockObject partialMockForObject:realObject];
[[[partialObject stub] andReturn:@"30.06 , 50.67"] getLocationTitle];
[partialObject viewDidLoad]; // Method under test
XCTAssertTrue([partialObject.title isEqualToString:@"30.06 , 50.67"], @"View controller title is wrong");

我发现尝试模拟alloc会导致行为困难。

修改

// In MyViewController
- (RAMImsakyaDataController*)dataController {
    if (!_dataController) {
        _dataController = [[RAMImsakyaDataController alloc] init];
    }
    return _dataController;
}

Then partial mock the VC and replace this method with one that returns your partially mocked data controller.

答案 1 :(得分:0)

我的猜测是OCMock无法正确模拟数据控制器的+alloc方法,因此您的视图控制器正在使用真实数据控制器而不是模拟。

我很难嘲笑对象创建。我最终做的不是尝试模拟+alloc而是将可测试性存根放在我想要测试的对象上创建它们的依赖项,然后我可以使用被测对象的部分模拟来覆盖对象创建。像:

@implementation ViewController
  - (void)init {
    ...
    _dataController = [self newDataController];
    ...
  }

  - (DataController *)newDataController {
    return [[DataController alloc] init];
  }
@end

然后在我的测试中

ViewController *underTest = [ViewController alloc];
id mockUnderTest = [OCMockObject partialMockForObject:underTest];
id mockDataController = [OCMockObject niceMockForClass:[DataController class]];
[[[mockUnderTest stub] andReturn:[mockDataController retain]] newDataController];
underTest = [underTest init];