В чем разница: Mockito doReturn().when() и when().thenReturn()
Быстрый ответ
doReturn()
подходит для использования с шпионами (spies), так как предотвращает выполнение реального метода и нежелательные побочные эффекты. В то же время, when()
более предпочтителен для использования с моками (mocks). Иногда doReturn()
используется, когда есть необходимость избежать возможности исключения в методе.
// Используем doReturn() для безопасности
doReturn("safe").when(spyList).get(0);
// Предпочитаем использовать when() в обычной ситуации
when(mockList.get(0)).thenReturn("standard");
Преимущества doReturn() для создания заглушек
Работа с void методами и шпионами
Использование doReturn()
оправдано, когда необходимо стабилизировать void метод или работать с шпионом Mockito. Это позволяет избавиться от выполнения реального метода и его недожелательных последствий.
// Создаем заглушку для void метода на профессиональном уровне
doReturn().when(spyList).clear();
// Этот код вызовет исключение UnnecessaryStubbingException
// doNothing().when(spyList).clear();
Избежание побочных эффектов
С doReturn()
нет необходимости беспокоиться о побочных эффектах при стабилизации метода, поскольку он не будет выполнен. Это особенно ценно в случае методов, которые воздействуют на глобальное состояние или взаимодействуют с внешними системами.
// Гарантируем, что все будет под контролем
doReturn("state-safe").when(mockObject).methodThatAltersState();
Переопределение предыдущих заглушек
Вы можете использовать doReturn()
для того, чтобы переопределить ранее установленные заглушки с исключениями, что дает возможность адаптировать поведение мока в процессе тестирования.
// Изменяем предыдущую заглушку, которая генерирует исключение
when(mockList.get(anyInt())).thenThrow(new RuntimeException());
doReturn("recovered").when(mockList).get(0);
when().thenReturn() для строгой типизации и читаемости
when().thenReturn()
более предпочтителен в отношении читаемости и строгой типизации. Он ясно показывает намерения по созданию заглушки и позволяет обнаружить ошибки при настройке тестов на этапе компиляции.
// Создаем стаб с понятным и безопасным кодом
when(mockList.get(0)).thenReturn("type-safe");
Визуализация
doReturn()
и when()
можно сравнить с тем, как ведете себя при организации сюрприза на вечеринке:
doReturn(): Секретный Конверт 📩
- Готовите сюрприз (результат) и помещаете его в конверт (заглушку) заранее.
- Содержимое остается НЕИЗМЕННЫМ, не зависит от событий на вечеринке (реальных вызовов методов).
when(): Организатор Вечеринок 🎉
- Готовите сюрпризы (результаты) в зависимости от приглашений (вызовов методов).
- Есть возможность для адаптации, но появление незапланированного гостя (исключения) может испортить вечеринку (тест).
Выберите подход, который наиболее подходит к вашей конкретной ситуации:
Используйте 📩, когда:
- Требуется конкретный результат без вызова реального метода.
Предпочитайте 🎉, когда:
- Важна гибкость, а все методы «вежливы».
Согласованность и достижение целостности методов
Единство в синтаксисе
Для упрощения и единообразия кода полезно овладеть одним типом синтаксиса. Если ваши тесты не связаны со сложными случаями и шпионами, то «when().thenReturn()
» может стать наиболее удобным из-за своей наглядности.
// Демонстрируем стандартное создание заглушек через when()
when(mockList.get(0)).thenReturn("consistent");
Работа с исключениями и многократные вызовы
doReturn().when()
особенно полезен для методов, которые предполагают различные результаты при последовательных вызовах или генерируют исключения.
// Значения заглушки, меняющиеся с каждым вызовом
doReturn("first-call").doReturn("second-call").when(mockList).get(anyInt());
// Генерация исключения с помощью заглушки
doThrow(new RuntimeException()).when(mockList).clear();
Совершенствование чистого кода
Устранение «запаха» кода
Переопределение заглушек можно считать «запахом» кода. Поэтому желательно стремиться к созданию предсказуемых и согласованных тестов для облегчения работы.
Контекст имеет значение
От величайшей важности наиболее подходящий подход для цепочки вызовов. Правильный выбор стратегии стабилизации помогает сократить усилия, минимизировать риск ошибок и упростить процесс тестирования.
Полезные материалы
- Mockito – mockito-core 5.10.0 javadoc — официальная документация по методам
doReturn()
иwhen()
Mockito. - java – Mockito – различия между doReturn() и when() – Stack Overflow — обсуждение на Stack Overflow, разъясняющее особенности
doReturn()
иwhen()
. - Unit tests with Mockito – Tutorial — руководство для модульного тестирования с использованием Mockito, включая
when
иdoReturn
. - org.mockito.Mockito#doReturn — множество java-примеров кода для
doReturn
в Mockito. - Mockito When/Then vs DoReturn/When – YouTube — видео-руководство, демонстрирующее
when/then
в сравнении сdoReturn/when
в Mockito.