Применяем 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в категории потокобезопасности.


