bcoughlan bcoughlan - 3 months ago 11
Java Question

Mockito - separately verifying multiple invocations on the same method

import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.verify;

import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;


public class MockitoTest {


public static class TestMock {
public void doIt(String s) {
}
}

public static void main(String[] args) {
TestMock mock = Mockito.mock(TestMock.class);
mock.doIt("1");
mock.doIt("2");

ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock, atLeastOnce()).doIt(argument.capture());
System.out.println(argument.getValue());
verify(mock, atLeastOnce()).doIt(argument.capture());
System.out.println(argument.getValue());
}
}


I expected this to print
1 2
but it instead prints
2 2
. It seems the '1' invocation is lost. Is there a way that I can verify that verifications happened with
1
and then
2
?

Answer

You can call ArgumentCaptor.getAllValues() instead of getValue(). This will return all captured values:

Returns all captured values. Use it in case the verified method was called multiple times.

In this case, it will return a List<String> containing 1 and 2.

The getValue() method only returns the last captured value:

Returns the captured value of the argument.

If the method was called multiple times then it returns the latest captured value

In your code, you can replace atLeastOnce() with the more precise times(2) since the mock was called 2 times. You don't need to have two distinct calls to verify to capture the arguments: Mockito will be able to capture all arguments passed to the mock with just one call.

TestMock mock = Mockito.mock(TestMock.class);
mock.doIt("1");
mock.doIt("2");

ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock, times(2)).doIt(argument.capture()); // verify that it was call 2 times and capture the values given

System.out.println(argument.getAllValues());