通过使用OCMock进行存根来覆盖方法

时间:2012-08-20 19:23:05

标签: objective-c ocunit ocmock

我正在尝试测试一个级别完成后停止计时器对象..我有以下代码:

-(void)advanceLevel {
    int nextLevelId = self.currentLevel.id + 1;

    self.currentLevel = [[Level alloc] initWithIdentifier:nextLevelId];

    [self.timer stop];
    [self prepareLevel];
}

...

prepareLevel方法重置计时器值并在其上调用“start” - 所以为了测试advanceLevel实际上是否停止了计时器,我需要覆盖prepareLevel方法。

所以在我的单元测试中,我做了以下事情:

-(void)testItStopsTheTimer {
    [timer start];

    id mockGame = [OCMockObject partialMockForObject:game];
    [[[mockGame stub] andReturn:nil] prepareLevel];

    [game advanceLevel];

    STAssertFalse(timer.active, nil);
}

导致XCode说“testItStopsTheTimer(游戏测试)失败。在子类转发器中结束游戏-0x12383060 .......”

那么,是否不可能将现有方法存根并将其替换为虚无?

2 个答案:

答案 0 :(得分:2)

OCMock绝对可以做你想做的事。

prepareLevel的方法签名是什么?如果它返回void,则模拟设置应为:

[[mockGame stub] prepareLevel];

[[[mockGame stub] andReturn:nil] prepareLevel];

答案 1 :(得分:1)

您正在尝试使用OCMock做的事情。在您的测试代码中,一行突出:

id mockGame = [OCMockObject partialMockForObject:game];

问题是,“游戏”来自哪里?是否在多个测试中使用相同的实例?您看到的错误可能是由以下序列引起的:您在部分模拟上使用expect,调用了预期的方法,然后再次调用该方法,但现在没有任何期望,部分模拟不知道该怎么办。

更新:我刚刚更改了OCMock,因此在这种情况下,mock只是将方法转发给真实对象。请参阅:https://github.com/erikdoe/ocmock/commit/e03d4fe74465b4fe3fa33552e036de8986f8dec2