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

Я ожидал, что это напечатает 1 2, но вместо этого напечатает 2 2. Кажется, что вызов "1" потерян. Есть ли способ проверить, что проверки произошли с 1, а затем 2?

Ответ 1

Вы можете вызвать ArgumentCaptor.getAllValues() вместо getValue(). Это вернет все зафиксированные значения:

Возвращает все зафиксированные значения. Используйте его при захвате varargs или когда вызванный метод вызывается несколько раз.

В этом случае он вернет a List<String>, содержащий 1 и 2.

Метод getValue() возвращает только последнее зафиксированное значение:

Возвращает захваченное значение аргумента.

Если метод вызывается несколько раз, он возвращает последнее зафиксированное значение

В вашем коде вы можете заменить atLeastOnce() на более точный times(2), так как mock вызывается 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());

Ответ 2

Переключитесь на 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));

Ответ 3

В конце концов мне действительно нужно было проверить порядок для инкрементной проверки, используя вызовы() 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());
    }
}