Применяем Mockito: когда использовать doAnswer и thenReturn
Быстрый ответ
Если требуется возвратить фиксированное значение, лучше всего использовать thenReturn()
, оно обеспечивает концизную подстановку:
// Все как у верной собаки, её добыча всегда предсказуема
when(mock.someMethod()).thenReturn(value);
Когда необходимо добавить логику в ответ, выбирайте doAnswer()
:
// Более похоже на кота, предсказуемого, но способного удивить
doAnswer(invocation -> "ответ основан на " + invocation.getArgument(0))
.when(mock).someMethod(any());
Искусство правильного выбора метода подстановки
Если нужно статическое значение — выбирайте thenReturn
Метод thenReturn()
— ваш надежный спутник для фиксированной подстановки — он всецело обеспечит возврат того же результата:
// Это словно ежедневное наслаждение одним и тем же блюдом. Ожидаемо, но вкусно!
when(mock.myMethod()).thenReturn(myFixedValue);
Если метод вызывается в тесте множество раз, thenReturn()
позволяет установить цепочку ответов на последующие вызовы:
// Все как в сериале с запланированными сюжетными поворотами
when(mock.myMethod()).thenReturn(firstValue, secondValue, thirdValue);
Для динамичных возвращаемых значений подойдет doAnswer
doAnswer()
идеально справляется, когда необходим динамический ответ. С ним ваша подстановка способна формироваться на основе аргументов, как многогранное блюдо от шеф-повара:
// Это как создание коктейля: различные ингредиенты создают уникальный вкус
doAnswer(invocation -> {
Integer input = invocation.getArgument(0);
return input * 2; // Создаем ответ
}).when(mock).myMethod(anyInt());
doAnswer()
также позволяет осуществлять дополнительные операции при вызове метода, например, изменять состояние или проверять аргументы.
Для методов с возратом void также подойдет doAnswer
При использовании методов void
doAnswer()
может воздействовать на методы, изменяющие состояние или генерирующие побочные эффекты, как в процессе строительства замка по эскизу:
// Это как приключение по карте, где заранее известны драконьи территории
doAnswer(invocation -> {
System.out.println("Метод вызван с аргументами: " + Arrays.toString(invocation.getArguments()));
return null; // Возвращаем null для методов void
}).when(mock).voidMethod(any());
Ненавязчивое наблюдение с помощью doAnswer
Хотите наблюдать за объектами без активизации их реального поведения? doAnswer()
обеспечивает безопасную подмену методов, идеальную для тестов:
// Все как у ниндзя, оставаясь незамеченным
doAnswer(invocation -> "значение-заглушка").when(spy).myRealMethod();
Альтернатива в виде doReturn
doReturn()
— это простой аналог thenReturn()
, который стоит использовать, чтобы избежать выполнения логики реального метода:
// Это как тайный проход, спасающий от встречи с драконом
doReturn("значение-заглушка").when(spy).myRealMethod();
Визуализация
Давайте приведем основные различия между методами doAnswer
и thenReturn
в виде таблицы:
Метод Mockito | Когда предпочтительнее его использовать |
---|---|
thenReturn | Простые задачи. Фиксированный ответ |
doAnswer | Сложные задачи. Динамические ответы |
// thenReturn
– Это как заказать стандартный бургер: без неожиданностей, ровно как и ожидали:
when(mock.someMethod()).thenReturn("фиксированный ответ");
// doAnswer
– Это как создать собственный рецепт суши-ролла: творческий процесс с простором для импровизации:
when(mock.someMethod()).doAnswer(invocation -> {
Object arg0 = invocation.getArgument(0);
return "ответ создан на основе " + arg0;
});
Все ясно на практических примерах
Имитация исключений при помощи doAnswer
doAnswer()
позволяет смоделировать поведение кода при возникновении исключений. Это как тест-драйв для вашего кода:
doAnswer(invocation -> {
if ("bad".equals(invocation.getArgument(0))) {
throw new IllegalArgumentException("Пожалуйста, держитесь подальше от неприятностей!");
}
return "а вот и ответ";
}).when(mock).someMethod(anyString());
Имитация временных задержек
При необходимости смоделировать замедленную работу или временные задержки doAnswer()
выполняет роль машины времени:
doAnswer(invocation -> {
Thread.sleep(1000L); // Добавляем задержку для эффекта
return "Приветствие из будущего!";
}).when(mock).someMethod();
Сложная логика в возвращаемых значениях
Когда требуются дополнительные вычисления или результат зависит от внешних условий, doAnswer()
дает простор для творчества:
doAnswer(invocation -> {
if (someExternalCondition) {
return "состояние достигнуто";
}
return "стандартный ответ";
}).when(mock).someMethod();
Полезные материалы
- Официальная документация Mockito по подстановке методов — авторитетный источник для детального изучения темы.
- Юнит-тестирование с Mockito: обучающий материал — подробное руководство с продвинутыми техниками и советами.
- Примеры кода на Java для Mockito doAnswer – ProgramCreek — коллекция практичных примеров использования
Mockito.doAnswer
. - Руководство по юнит-тестированию с Mockito | Toptal — обзор ежедневно применяемых методик работы с Mockito.
- Reddit – Обсуждение вопроса — отзывы о
doAnswer
противthenReturn
в категории потокобезопасности.