Search code examples
iosobjective-ctddocmockito

OCMockito - Verify order of method invocations


As far as I can see, there is no way to verify the order of method invocations on a mock.
Or am I missing something?

- (void)testResetCameraState_resetsCameraView
{
   // Arrange
   [given([_cameraManagerMock previewLayer]) willReturn:_testLayer];

   // Act
   [_cameraInteractor resetCameraState];

   // Assert
   [verifyCount(_cameraViewMock, times(1)) resetPreview];
   [verifyCount(_cameraViewMock, times(1)) setPreviewLayer:_testLayer];
}

In this case you cannot verify, that the setPreviewLayer: is called after resetPreview.


Solution

  • I think I found a solution.
    It's based on the givenVoid method added in this pull request: https://github.com/jonreid/OCMockito/pull/93

    Sadly it is not merged yet, so you need to download and build this version by yourself: https://github.com/lysannschlegel/OCMockito/tree/given_void

    With the new method you can verify the order of method calls in the following way:

    - (void)testResetCameraState_resetsCameraView
    {
        // Arrange
        [given([_cameraManagerMock previewLayer]) willReturn:_testLayer];
        [givenVoid([self->_cameraViewMock resetPreview]) willDo:^id (NSInvocation *invocation)
         {
             [(MKTBaseMockObject*)self->_cameraViewMock reset];
             return nil;
         }];
    
        // Act
        [_cameraInteractor resetCameraState];
    
        // Assert
        [verifyCount(_cameraViewMock, never()) resetPreview];
        [verifyCount(_cameraViewMock, times(1)) setPreviewLayer:_testLayer];
    }
    

    This will reset the mock after the first call of resetPreview.
    So we can verify stuff after that call:

    1. resetPreview is never called after the first call.
    2. setPreviewLayer is called after resetPreview.

    The reset call also resets the givenVoid() willDo: so a second reset call wouldn't reset the mock again.

    Hope this helps, happy coding :D