Имитация первого вызова не удалась, второй вызов завершен
Я хочу использовать Mockito для тестирования (упрощенного) кода ниже. Я не знаю, как сказать Мокито сбой в первый раз, а затем добиться успеха во второй раз.
for(int i = 1; i < 3; i++) {
String ret = myMock.doTheCall();
if("Success".equals(ret)) {
log.write("success");
} else if ( i < 3 ) {
log.write("failed, but I'll try again. attempt: " + i);
} else {
throw new FailedThreeTimesException();
}
}
Я могу настроить тест успеха с помощью:
Mockito.when(myMock).doTheCall().thenReturn("Success");
И тест с ошибкой:
Mockito.when(myMock).doTheCall().thenReturn("you failed");
Но как я могу проверить, что если он сработает один раз (или дважды), то он будет выполнен успешно?
Ответы
Ответ 1
От документы:
Иногда нам нужно заглушить с другим возвращаемым значением/исключением для одного и того же вызова метода. Типичным вариантом использования могут быть издевательские итераторы. У оригинальной версии Mockito не было этой функции, чтобы продвигать простое издевательство. Например, вместо итераторов можно использовать Iterable или просто коллекции. Они предлагают естественные способы укупорки (например, с использованием реальных коллекций). В редких сценариях последовательные звонки могут быть полезны:
when(mock.someMethod("some arg"))
.thenThrow(new RuntimeException())
.thenReturn("foo");
//First call: throws runtime exception:
mock.someMethod("some arg");
//Second call: prints "foo"
System.out.println(mock.someMethod("some arg"));
Итак, в вашем случае вам нужно:
when(myMock.doTheCall())
.thenReturn("You failed")
.thenReturn("Success");
Ответ 2
Самый короткий способ написать то, что вам нужно, -
when(myMock.doTheCall()).thenReturn("Success", "you failed");
Когда вы передаете несколько аргументов в thenReturn
, как это, каждый аргумент будет использоваться не более одного раза, за исключением самого последнего аргумента, который используется столько раз, сколько необходимо. Например, в этом случае, если вы сделаете звонок 4 раза, вы получите "Успех", "вы не выполнили" , "вы не выполнили" , "вы не выполнили" .
Ответ 3
Поскольку комментарий, связанный с этим, трудно читать, я добавлю отформатированный ответ.
Если вы пытаетесь сделать это с помощью функции void, которая просто генерирует исключение с последующим шагом без поведения, то вы должны сделать что-то вроде этого:
Mockito.doThrow(new Exception("MESSAGE"))
.doNothing()
.when(mockService).method(eq());
Ответ 4
Чтобы добавить к этому и этому ответу, вы также можете использовать цикл для цепочки ложных вызовов. Это полезно, если вам нужно издеваться над одной и той же вещью несколько раз или по какой-то схеме.
Например (хотя и притянутый за уши):
import org.mockito.stubbing.Stubber;
Stubber stubber = doThrow(new Exception("Exception!"));
for (int i=0; i<10; i++) {
if (i%2 == 0) {
stubber.doNothing();
} else {
stubber.doThrow(new Exception("Exception"));
}
}
stubber.when(myMockObject).someMethod(anyString());
Ответ 5
У меня другая ситуация, я хотел макетировать void
функцию для первого вызова и нормально ее запускать при втором вызове.
Это работает для меня:
Mockito.doThrow(new RuntimeException("random runtime exception")).doCallRealMethod().when(object).method(Mockito.any());