Mockito可以捕获多次调用方法的参数吗?
我有一个被调用两次的方法,我想捕获第二个方法调用的参数。
以下是我所尝试的:
ArgumentCaptor<Foo> firstFooCaptor = ArgumentCaptor.forClass(Foo.class); ArgumentCaptor<Foo> secondFooCaptor = ArgumentCaptor.forClass(Foo.class); verify(mockBar).doSomething(firstFooCaptor.capture()); verify(mockBar).doSomething(secondFooCaptor.capture()); // then do some assertions on secondFooCaptor.getValue()
但是我得到了TooManyActualInvocations
exception,因为Mockito认为doSomething
只能被调用一次。
我该如何validationdoSomething
的第二个调用的参数?
我认为应该是
verify(mockBar, times(2)).doSomething(...)
来自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());
如果你不想validation所有对doSomething()
的调用,只有最后一个,你可以使用ArgumentCaptor.getValue()
。 根据Mockito javadoc :
如果该方法被多次调用,则返回最新的捕获值
所以这将工作(假设Foo
有一个方法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());
由于Mockito 2.0也有可能使用静态方法Matchers.argThat(ArgumentMatcher) 。 在Java 8的帮助下,它现在更清晰,更易读:
verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("OneSurname"))); verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("AnotherSurname")));
如果你被绑定到较低的Java版本,那也不是那么糟糕:
verify(mockBar).doSth(argThat(new ArgumentMatcher<Employee>() { @Override public boolean matches(Object emp) { return ((Employee) emp).getSurname().equals("SomeSurname"); } }));
当然,这些都不能validation呼叫顺序 – 您应该使用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")));
请看看mockito-java8项目, 这个项目可以进行如下调用:
verify(mockBar).doSth(assertArg(arg -> assertThat(arg.getSurname()).isEqualTo("Surname")));