Mockito能否捕获多次调用的方法的参数?

2022-08-31 04:19:54

我有一个被调用两次的方法,我想捕获第二个方法调用的参数。

以下是我尝试过的方法:

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()

但我得到了一个例外,因为Mockito认为它只应该叫一次。TooManyActualInvocationsdoSomething

如何验证 第二次调用的参数 ?doSomething


答案 1

我认为应该是

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());

答案 2

从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");
        }
    }));

当然,这些都不能验证调用的顺序 - 您应该使用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")));

推荐