1

I am trying to test that a timer object is stopped after a level is completed.. I have the following code:

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

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

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

...

The prepareLevel method resets the timer value and calls "start" on it--- so in order to test that advanceLevel actually stops the timer, I need to overwrite the prepareLevel method.

So in my unit test, I did the following:

-(void)testItStopsTheTimer {
    [timer start];

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

    [game advanceLevel];

    STAssertFalse(timer.active, nil);
}

Which results in XCode saying "testItStopsTheTimer (Gametests) failed. Ended up in subclass forwarder for Game-0x12383060......."

So, is it not possible to stub out an existing method and replace it with nothingness?

patrick
  • 9,290
  • 13
  • 61
  • 112

2 Answers2

2

What you're trying to do is definitely possible with OCMock.

What is the method signature for prepareLevel? If it returns void, your mock setup should be:

[[mockGame stub] prepareLevel];

not:

[[[mockGame stub] andReturn:nil] prepareLevel];
Christopher Pickslay
  • 17,523
  • 6
  • 79
  • 92
1

What you are trying to do is possible with OCMock. In your test code one lines stands out:

id mockGame = [OCMockObject partialMockForObject:game];

The question is, where does "game" come from? Is the same instance used in multiple tests? The error you are seeing can be caused by the following sequence: you are using expect on a partial mock, the expected method is called, then you are called the method again, but now there's no expectation left and the partial mock doesn't know what to do.

UPDATE: I have just changed OCMock so that in such cases the mock simply forwards the method to the real object. See: https://github.com/erikdoe/ocmock/commit/e03d4fe74465b4fe3fa33552e036de8986f8dec2

Erik Doernenburg
  • 2,933
  • 18
  • 21
  • I get this error still if I pass in an arg to the expect method that doesn't match the arg passed in while running the test. If I pass the correct arg to the expect method, the test passes just fine? Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Ended up in subclass forwarder for KIViewController-0x12c17740-380651950.550829 with unstubbed method operationsDidFinishWithError:' – Collin Jan 23 '13 at 16:51