Java Mockito - 在同一方法上分别验证多个调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35320568/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:33:07  来源:igfitidea点击:

Mockito - separately verifying multiple invocations on the same method

javamockito

提问by bcoughlan

import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.verify;

import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;


public class MockitoTest {


    public static class TestMock {
        public void doIt(String s) {
        }
    }

    public static void main(String[] args) {
        TestMock mock = Mockito.mock(TestMock.class);
        mock.doIt("1");
        mock.doIt("2");

        ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
        verify(mock, atLeastOnce()).doIt(argument.capture());
        System.out.println(argument.getValue());
        verify(mock, atLeastOnce()).doIt(argument.capture());
        System.out.println(argument.getValue());
    }
}

I expected this to print 1 2but it instead prints 2 2. It seems the '1' invocation is lost. Is there a way that I can verify that verifications happened with 1and then 2?

我希望这会打印,1 2但它会打印2 2. 似乎“1”调用丢失了。有没有办法可以验证验证是否发生在1然后2

采纳答案by Tunaki

You can call ArgumentCaptor.getAllValues()instead of getValue(). This will return all captured values:

您可以调用ArgumentCaptor.getAllValues()而不是getValue(). 这将返回所有捕获的值:

Returns all captured values. Use it when capturing varargs or when the verified method was called multiple times.

返回所有捕获的值。在捕获可变参数或多次调用验证方法时使用它。

In this case, it will return a List<String>containing 1and 2.

在这种情况下,它将返回一个List<String>包含12

The getValue()method only returns the last captured value:

getValue()方法只返回最后捕获的值:

Returns the captured value of the argument.

If the method was called multiple times then it returns the latest captured value

返回参数的捕获值。

如果多次调用该方法,则返回最新捕获的值

In your code, you can replace atLeastOnce()with the more precise times(2)since the mock was called 2 times. You don't need to have two distinct calls to verifyto capture the arguments: Mockito will be able to capture all arguments passed to the mock with just one call.

在您的代码中,您可以替换atLeastOnce()为更精确的,times(2)因为模拟被调用了 2 次。您不需要有两个不同的调用来verify捕获参数:Mockito 只需一次调用即可捕获传递给模拟的所有参数。

TestMock mock = Mockito.mock(TestMock.class);
mock.doIt("1");
mock.doIt("2");

ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock, times(2)).doIt(argument.capture()); // verify that it was call 2 times and capture the values given

System.out.println(argument.getAllValues());

回答by Todd

Switch to getAllValues()from getValues(). It will return a list of all the captures it performs on your mock.

切换到getAllValues()getValues()。它将返回它在模拟上执行的所有捕获的列表。

ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock, atLeastOnce()).doIt(argument.capture());
System.out.println(argument.getAllValues().get(0));
verify(mock, atLeastOnce()).doIt(argument.capture());
System.out.println(argument.getAllValues().get(1));

回答by bcoughlan

What I actually needed in the end was in-order verification for incremental verification, using the calls() VerificationMode

最后我真正需要的是增量验证的顺序验证,使用 call() VerificationMode

public static class A {

    public void a(int x) {}

    public void b() {}

}

public static void main(String[] args) {
    A a = mock(A.class);
    a.b();
    a.a(1);
    a.a(1);
    a.a(2);
    a.a(3);
    a.a(4);

    InOrder inOrder = Mockito.inOrder(a);
    // Verifies [1,1]
    inOrder.verify(a, calls(2)).a(1);
    {
        // Verifies [2]
        ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
        inOrder.verify(a, calls(1)).a(argument.capture());
        System.out.println(argument.getAllValues());
    }
    {
        // Verifies [3,4]
        ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
        inOrder.verify(a, calls(2)).a(argument.capture());
        System.out.println(argument.getAllValues());
    }
}