【问题标题】:overwriting a method via stubbing with OCMock通过 OCMock 存根覆盖方法
【发布时间】:2012-08-20 19:23:04
【问题描述】:

我正在尝试测试一个计时器对象在关卡完成后是否停止。我有以下代码:

-(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 (Gametests) failed. Ended up in subclass forwarder for Game-0x12383060.......”

那么,是不是不能把现有的方法存根,然后用虚无代替呢?

【问题讨论】:

    标签: objective-c ocunit ocmock


    【解决方案1】:

    OCMock 绝对可以实现您想要做的事情。

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

    [[mockGame stub] prepareLevel];
    

    不是:

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

    【讨论】:

      【解决方案2】:

      OCMock 可以实现您想要做的事情。在您的测试代码中,有一行突出:

      id mockGame = [OCMockObject partialMockForObject:game];
      

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

      更新:我刚刚更改了 OCMock,以便在这种情况下,模拟只是将方法转发给真实对象。见:https://github.com/erikdoe/ocmock/commit/e03d4fe74465b4fe3fa33552e036de8986f8dec2

      【讨论】:

      • 如果我将 arg 传递给与运行测试时传入的 arg 不匹配的期望方法,我仍然会收到此错误。如果我将正确的 arg 传递给 expect 方法,测试就可以通过了吗?由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“在 KIViewController-0x12c17740-380651950.550829 的子类转发器中结束,带有未存根的方法操作操作DidFinishWithError:”
      猜你喜欢
      • 2015-06-19
      • 1970-01-01
      • 2023-04-03
      • 2015-04-09
      • 1970-01-01
      • 1970-01-01
      • 2014-03-17
      • 2012-07-26
      • 1970-01-01
      相关资源
      最近更新 更多