Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mockito verify interactions with ArgumentCaptor

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?

like image 574
Hilikus Avatar asked Jun 20 '13 02:06

Hilikus


People also ask

What does ArgumentCaptor do in Mockito?

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.

How do you verify a method called in Mockito?

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.

Which method in Mockito verifies that no interaction has happened with a mock in Java?

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.


1 Answers

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.

like image 83
Ryan Stewart Avatar answered Sep 18 '22 16:09

Ryan Stewart