To check the number of interactions with a mock where the parameter in the method call is of a certain type, one can do
mock.someMethod(new FirstClass()); mock.someMethod(new OtherClass()); verify(mock, times(1)).someMethod(isA(FirstClass.class));
This will pass thanks to the call to isA
since someMethod
was called twice but only once with argument FirstClass
However, this pattern seems to not be possible when using an ArgumentCaptor, even if the Captor was created for the particular argument FirstClass
this doesn't work
mock.someMethod(new FirstClass()); mock.someMethod(new OtherClass()); ArgumentCaptor<FirstClass> captor = ArgumentCaptor.forClass(FirstClass.class); verify(mock, times(1)).someMethod(captor.capture());
it says the mock was called more than once.
Is there any way to accomplish this verification while capturing the argument for further checking?
Mockito ArgumentCaptor is used to capture arguments for mocked methods. ArgumentCaptor is used with Mockito verify() methods to get the arguments passed when any method is called. This way, we can provide additional JUnit assertions for our tests.
Mockito verify() method can be used to test number of method invocations too. We can test exact number of times, at least once, at least, at most number of invocation times for a mocked method. We can use verifyNoMoreInteractions() after all the verify() method calls to make sure everything is verified.
Mockito verifyZeroInteractions() method It verifies that no interaction has occurred on the given mocks. It also detects the invocations that have occurred before the test method, for example, in setup(), @Before method or the constructor.
I recommend using Mockito's Hamcrest integration to write a good, clean matcher for it. That allows you to combine the verification with detailed checking of the passed argument:
import static org.mockito.hamcrest.MockitoHamcrest.argThat; verify(mock, times(1)).someMethod(argThat(personNamed("Bob"))); Matcher<Person> personNamed(final String name) { return new TypeSafeMatcher<Person>() { public boolean matchesSafely(Person item) { return name.equals(item.getName()); } public void describeTo(Description description) { description.appendText("a Person named " + name); } }; }
Matchers generally lead to more readable tests and more useful test failure messages. They also tend to be very reusable, and you'll find yourself building up a library of them tailored for testing your project. Finally, you can also use them for normal test assertions using JUnit's Assert.assertThat()
, so you get double use out of them.
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