Я использую Mockito для последующего тестирования модулей. Я смущен , когда использовать doAnswer
против thenReturn
.
Кто-нибудь может мне подробно помочь? Пока что пробовал с thenReturn
.
Я использую Mockito для последующего тестирования модулей. Я смущен , когда использовать doAnswer
против thenReturn
.
Кто-нибудь может мне подробно помочь? Пока что пробовал с thenReturn
.
Ответы:
Вам следует использовать thenReturn
или, doReturn
если вы знаете возвращаемое значение во время имитации вызова метода. Это определенное значение возвращается, когда вы вызываете фиктивный метод.
thenReturn(T value)
Задает возвращаемое значение, которое будет возвращено при вызове метода.
@Test
public void test_return() throws Exception {
Dummy dummy = mock(Dummy.class);
int returnValue = 5;
// choose your preferred way
when(dummy.stringLength("dummy")).thenReturn(returnValue);
doReturn(returnValue).when(dummy).stringLength("dummy");
}
Answer
используется, когда вам нужно выполнить дополнительные действия при вызове имитационного метода, например, когда вам нужно вычислить возвращаемое значение на основе параметров вызова этого метода.
Используйте,
doAnswer()
когда вы хотите заглушить метод void с помощью genericAnswer
.Ответ определяет выполняемое действие и возвращаемое значение, которое возвращается при взаимодействии с макетом.
@Test
public void test_answer() throws Exception {
Dummy dummy = mock(Dummy.class);
Answer<Integer> answer = new Answer<Integer>() {
public Integer answer(InvocationOnMock invocation) throws Throwable {
String string = invocation.getArgumentAt(0, String.class);
return string.length() * 2;
}
};
// choose your preferred way
when(dummy.stringLength("dummy")).thenAnswer(answer);
doAnswer(answer).when(dummy).stringLength("dummy");
}
Answer
just with return UUID.randomUUID();
.
Answer
- это функциональный интерфейс, поэтому в Java 8 вы можете заменить его лямбда-выражением. Если он недостаточно чистый, возможен любой другой обычный и необычный рефакторинг.
doAnswer
и thenReturn
сделайте то же самое, если:
Давайте посмеемся над этим BookService
public interface BookService {
String getAuthor();
void queryBookTitle(BookServiceCallback callback);
}
Вы можете заглушить getAuthor (), используя doAnswer
и thenReturn
.
BookService service = mock(BookService.class);
when(service.getAuthor()).thenReturn("Joshua");
// or..
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return "Joshua";
}
}).when(service).getAuthor();
Обратите внимание, что при использовании doAnswer
вы не можете передать метод when
.
// Will throw UnfinishedStubbingException
doAnswer(invocation -> "Joshua").when(service.getAuthor());
Итак, когда бы вы использовали doAnswer
вместо thenReturn
? Я могу придумать два варианта использования:
Используя doAnswer, вы можете выполнять некоторые дополнительные действия при вызове метода. Например, вызовите обратный вызов для queryBookTitle.
BookServiceCallback callback = new BookServiceCallback() {
@Override
public void onSuccess(String bookTitle) {
assertEquals("Effective Java", bookTitle);
}
};
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
BookServiceCallback callback = (BookServiceCallback) invocation.getArguments()[0];
callback.onSuccess("Effective Java");
// return null because queryBookTitle is void
return null;
}
}).when(service).queryBookTitle(callback);
service.queryBookTitle(callback);
При использовании when-thenReturn в Spy Mockito вызовет реальный метод и затем заглушит ваш ответ. Это может вызвать проблему, если вы не хотите вызывать реальный метод, как в этом примере:
List list = new LinkedList();
List spy = spy(list);
// Will throw java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
when(spy.get(0)).thenReturn("java");
assertEquals("java", spy.get(0));
Используя doAnswer, мы можем безопасно его заглушить.
List list = new LinkedList();
List spy = spy(list);
doAnswer(invocation -> "java").when(spy).get(0);
assertEquals("java", spy.get(0));
На самом деле, если вы не хотите выполнять дополнительные действия при вызове метода, вы можете просто использовать doReturn
.
List list = new LinkedList();
List spy = spy(list);
doReturn("java").when(spy).get(0);
assertEquals("java", spy.get(0));
doAnswer(new Answer() { ... return null;}
я получаю предупреждение в eclipse: «Ответ - это необработанный тип. Ссылки на общий тип Answer <T> должны быть параметризованы». Есть ли способ решить эту проблему (кроме игнорирования предупреждения c)?
code = UUID.randomUUID()
, я обнаружил, что это невозможно реализовать с помощьюmockito
.