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
?
thenAnswer( invocation -> { Object argument = invocation. getArguments()[1]; if (argument. equals(new ARequest(1, "A"))) { return new AResponse(1, "passed"); } else if (argument. equals(new ARequest(2, "2A"))) { return new AResponse(2, "passed"); } else if (argument.
Following are the differences between thenReturn and doReturn : * Type safety : doReturn takes Object parameter, unlike thenReturn . Hence there is no type check in doReturn at compile time. In the case of thenReturn , whenever the type mismatches during runtime, the WrongTypeOfReturnValue exception is raised.
Mockito Argument Matcher - eq() When we use argument matchers, then all the arguments should use matchers. If we want to use a specific value for an argument, then we can use eq() method. when(mockFoo. bool(eq("false"), anyInt(), any(Object. class))).
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());
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));
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());
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With