Can Mockito capture arguments of a method called multiple times?
I think it should be
verify(mockBar, times(2)).doSomething(...)
Sample from mockito javadoc:
ArgumentCaptor<Person> peopleCaptor = ArgumentCaptor.forClass(Person.class);verify(mock, times(2)).doSomething(peopleCaptor.capture());List<Person> capturedPeople = peopleCaptor.getAllValues();assertEquals("John", capturedPeople.get(0).getName());assertEquals("Jane", capturedPeople.get(1).getName());
Since Mockito 2.0 there's also possibility to use static method Matchers.argThat(ArgumentMatcher). With the help of Java 8 it is now much cleaner and more readable to write:
verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("OneSurname")));verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("AnotherSurname")));
If you're tied to lower Java version there's also not-that-bad:
verify(mockBar).doSth(argThat(new ArgumentMatcher<Employee>() { @Override public boolean matches(Object emp) { return ((Employee) emp).getSurname().equals("SomeSurname"); } }));
Of course none of those can verify order of calls - for which you should use InOrder :
InOrder inOrder = inOrder(mockBar);inOrder.verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("FirstSurname")));inOrder.verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("SecondSurname")));
Please take a look at mockito-java8 project which makes possible to make calls such as:
verify(mockBar).doSth(assertArg(arg -> assertThat(arg.getSurname()).isEqualTo("Surname")));
If you don't want to validate all the calls to doSomething()
, only the last one, you can just use ArgumentCaptor.getValue()
. According to the Mockito javadoc:
If the method was called multiple times then it returns the latest captured value
So this would work (assumes Foo
has a method getName()
):
ArgumentCaptor<Foo> fooCaptor = ArgumentCaptor.forClass(Foo.class);verify(mockBar, times(2)).doSomething(fooCaptor.capture());//getValue() contains value set in second call to doSomething()assertEquals("2nd one", fooCaptor.getValue().getName());