Mockito - 分别验证同一方法的多个调用

bco*_*lan 24 java mockito

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Tun*_*aki 37

你可以打电话ArgumentCaptor.getAllValues()而不是getValue().这将返回所有捕获的值:

返回所有捕获的值.捕获varargs或多次调用经过验证的方法时使用它.

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

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

返回参数的捕获值.

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

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

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());
Run Code Online (Sandbox Code Playgroud)


Tod*_*odd 6

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));
Run Code Online (Sandbox Code Playgroud)


bco*_*lan 6

最后我真正需要的是增量验证的顺序验证,使用 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());
    }
}
Run Code Online (Sandbox Code Playgroud)