Frueps
Frueps

Reputation: 145

Mockito: InOrder.verify does not prohibit intermediate calls on a mock

I want to test, that a method on a mock gets called in the correct order, with the correct parameters and also the correct amount of method calls in regard to the corresponding parameters.

Let's assume I want to test, that List.add gets called Like this:

List<String> listMock = Mockito.mock(List.class);
listMock.add("A");
listMock.add("C");

InOrder inOrder = Mockito.inOrder(listMock);
inOrder.verify(listMock).add("A");
inOrder.verify(listMock).add("C");
inOrder.verifyNoMoreInteractions();

This test works fine, but it is not strict enough for my intentions. The problem is that if the actual invocation changes, the test will not necessarily fail. If you do something like this for example:

List<String> listMock = Mockito.mock(List.class);
listMock.add("A");
listMock.add("B");
listMock.add("C");

// this won't fail
InOrder inOrder = Mockito.inOrder(listMock);
inOrder.verify(listMock).add("A");
inOrder.verify(listMock).add("C");
inOrder.verifyNoMoreInteractions();

I do want to verify that add is called first with "A" and afterwards add is called with "C". In the meantime add shouldn't be called with anything at all.

The only solution I came up with is a combination of Mockito.verify and InOrder.verify:

// this works but doesn't seem very elegant
Mockito.verify(listMock, times(2)).add(Mockito.anyString());
InOrder inOrder = Mockito.inOrder(listMock);
inOrder.verify(listMock).add("A");
inOrder.verify(listMock).add("C");
inOrder.verifyNoMoreInteractions();

Now my testing logic is spread accross Mockito.verify and InOrder.verify.

Is there a more elegant solution which prohibits intermediate calls to add?

Upvotes: 4

Views: 1770

Answers (1)

Markus Steppberger
Markus Steppberger

Reputation: 638

You should call the verifyNoMoreInteractions() method on the mocked object to ensure no more invocations:

InOrder inOrder = Mockito.inOrder(listMock);
inOrder.verify(listMock).add("A");
inOrder.verify(listMock).add("C");
Mockito.verifyNoMoreInteractions(listMock);

That way the verify would fail if another call happens in between as it expects 2 calls and your example calls it 3 times. It also ensures the invocation with exactly the given arguments in exactly the desired order.

Upvotes: 3

Related Questions