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