Search code examples
objective-cocunitocmock

overwriting a method via stubbing with OCMock


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?


Solution

  • 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