Reputation: 26627
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
?
Upvotes: 37
Views: 35563
Reputation: 137289
You can call ArgumentCaptor.getAllValues()
instead of getValue()
. This will return all captured values:
Returns all captured values. Use it when capturing varargs or when 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());
Upvotes: 51
Reputation: 26627
What I actually needed in the end was in-order verification for incremental verification, using the calls() VerificationMode
public static class A {
public void a(int x) {}
public void b() {}
}
public static void main(String[] args) {
A a = mock(A.class);
a.b();
a.a(1);
a.a(1);
a.a(2);
a.a(3);
a.a(4);
InOrder inOrder = Mockito.inOrder(a);
// Verifies [1,1]
inOrder.verify(a, calls(2)).a(1);
{
// Verifies [2]
ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
inOrder.verify(a, calls(1)).a(argument.capture());
System.out.println(argument.getAllValues());
}
{
// Verifies [3,4]
ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
inOrder.verify(a, calls(2)).a(argument.capture());
System.out.println(argument.getAllValues());
}
}
Upvotes: 6
Reputation: 31720
Switch to getAllValues()
from getValues()
. It will return a list of all the captures it performs on your mock.
ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock, atLeastOnce()).doIt(argument.capture());
System.out.println(argument.getAllValues().get(0));
verify(mock, atLeastOnce()).doIt(argument.capture());
System.out.println(argument.getAllValues().get(1));
Upvotes: 7