6

I am experimenting with converting some of my unit tests from using JMock to using Mockito and have hit a few stumbling blocks.

Firstly in my tests when using JMock the verification and returning of the stub happen in one step as follows

    contextMockery.checking(new Expectations() {{
        oneOf(dateUtilityService).isBeforeToday(URGENT_DATE);
            will(returnValue(true));
    }});

This essentially verifies that the method is being called and returns a canned value at the same time. The test fails if isBeforeToday method is NOT called and returns my canned value of true at the same time. Whereas when using Mockito I have to verify that the method is being called and then return my canned value in separate steps which are pretty much a duplicate as follows:

    doReturn(true).when(dateUtilityService).isBeforeToday(URGENT_DATE);
    verify(dateUtilityService).isBeforeToday(URGENT_DATE);

Is there no way to do this in one step?

Secondly, if I forget to list a method call to one of my mocks in my expectations, JMock fails the test with "Unexpected invocation exception" which in my opinion is correct whereas Mockito will happily pass the test unless I explicitly verify that a method call to the mock must never happen, is this correct (seems wrong)? Is there a way to tell mockito to fail the test if unexpected method calls are made to my mocked out dependencies?

Clinton Bosch
  • 2,497
  • 4
  • 32
  • 46
  • Just out of curiosity, did you also consider converting the tests to JMockit? The syntax is much closer to jMock's: `new Expectations() {{ dateUtilityService.isBeforeToday(URGENT_DATE); result = true; }};`. – Rogério Jun 24 '14 at 19:18

1 Answers1

6

1.

When you stub a method call the verify method is usually not necessary - you should check the action based on the return value (in your case something might happen or something will be returned when the dateUtilityService returns true - check that instead of verifying interaction with a mock.

Mockito documentation also talks about this. http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html#2

2.

This actually leads to fragile tests and is not recommended way of doing things with mockito. That's why there is no way to set this behaviour.

See http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html#8

Greg Chabala
  • 1,125
  • 2
  • 23
  • 35
František Hartman
  • 14,436
  • 2
  • 40
  • 60
  • So that makes sense in some cases (like the one I showed) when the stub is changing a value on your return type. But as I mentioned in my second part of my question, if I forget to stub a method call (that may not change any return value) in my test, I would like to know about it so that I can make a concious choice to either stub the call or tell the test that it should never be called. – Clinton Bosch Jun 24 '14 at 18:00
  • 1
    @ClintonBosch You can add a call to `verifyNoMoreInteractions()` at the end of your test method, to detect any unstubbed calls. – Rogério Jun 24 '14 at 19:14
  • Since I started to use Mockito (I used JMock since 2007 or even before... I don't remember), I noticed green tests where colleagues forgot to call the collaborator, I heard sentences like "unit tests sometime give you false positive, it is better to have integration tests". Maybe, it is better to use a tool like JMock and try to avoid that "fragile tests" in another way instead of using so weak design tools like Mockito. – Sixro Apr 19 '16 at 17:39