Я використовую 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()
коли ви хочете заглушити недійсний метод із загальнимAnswer
.Відповідь вказує на дію, яка виконується, і повернене значення, яке повертається під час взаємодії з макетом.
@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 з 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;}
я отримую попередження у затемненні для "Відповідь - це необроблений тип. Посилання на загальний тип Відповідь <T> слід параметризувати". Чи є спосіб вирішити це питання (крім ігнорування попередження ofc)?
code = UUID.randomUUID()
, я виявив неможливим це реалізуватиmockito
.