Меняем возвращаемые значения в Mockito без ребилда моков
Быстрый ответ
С помощью библиотеки Mockito можно настроить поведение методов объекта-заглушки так, чтобы они возвращали разные значения при каждом новом вызове. Вам обязательно пригодятся в этом случае множественные вызовы метода thenReturn
:
SomeClass mock = mock(SomeClass.class);
when(mock.method()).thenReturn("Первый").thenReturn("Второй");
System.out.println(mock.method()); // Вывод на экран "Первый"
System.out.println(mock.method()); // Вывод на экран "Второй"
При первом вызове метод method()
вернёт "Первый", а при повторном вызове — "Второй".
Загадочный мир Mockito: уникальные значения, исключения и удивление
Последовательное возвращение уникальных значений
Метод thenReturn
принимает аргументы переменной длины (varargs), что позволяет настроить последовательность возвращаемых значений:
when(mock.method()).thenReturn("Первый вызов", "Второй вызов", "Халк разрушает!", "Четвертый вызов");
Таким образом, при каждом вызове будет возвращаться следующее значение из указанной последовательности. Фраза "Халк разрушает!" в последовательности для создания элемента неожиданности.
Имитация генерации исключений при помощи заглушек
Различные ситуации в процессе тестирования могут потребовать генерацию исключений. Для этого можно воспользоваться сочетанием методов thenReturn
и thenThrow
:
when(mock.method()).thenReturn("Хорошие времена").thenThrow(new RuntimeException());
Итак, при первом вызове метода вас ждут "Хорошие времена", но все последующие вызовы приведут к возникновению исключений.
Важность сброса состояния заглушек перед каждым тестом
Чтобы избежать влияния предыдущих тестов на следующие, рекомендуется сбрасывать состояние заглушек перед каждым тестом:
@Before
public void setup() {
reset(mock);
// Настройка заглушки перед следующим тестом
}
Данная практика обеспечивает "чистый" старт каждого теста.
Исключение реальных вызовов при работе с шпионами в Mockito
При работе с шпионами рекомендуется использовать doReturn()
вместо when()
, чтобы предотвратить реальные вызовы методов:
SomeClass spy = spy(new SomeClass());
doReturn("Контролируемый ответ").when(spy).method();
Таким образом, мы подменяем реальное поведение, не позволяя приложению выполнять настоящие действия.
Направление на создание изолированной тестовой среды
При прохождении каждого теста полезно создавать отдельные экземпляры заглушек, что можно выполнить в блоке @Before
:
private SomeClass mock;
@Before
public void setup() {
mock = mock(SomeClass.class);
// Настройка тестовой среды
}
Определение одной заглушки на каждый тест обеспечивает изоляцию тестов друг от друга.
Визуализация
Представьте себе вокзал с поездами (🚆), где каждый поезд — это уникальный вызов метода.
Первый вызов 🚆: Возвращает "📚"
Второй вызов 🚆: Возвращает "🎮"
Третий вызов 🚆: Возвращает "🏈"
Теперь, когда мы применяем Mockito, это можно представить как диалог с диспетчером:
mock.when(station.nextTrainArrives())
.thenReturn("📚")
.thenReturn("🎮")
.thenReturn("🏈");
В результате каждый вызов будет представлять собой уникальную грузоперевозку, в форме символической последовательности "📚🎮🏈".
Искусство работы с Mockito: Позитивные моменты, Трудности и Лучшие практики
Повышение читаемости кода при помощи цепных вызовов
Цепочечные вызовы методов упрощают код, естественным образом повышая его читаемость и помогая уменьшить объём кода:
when(mock.method())
.thenReturn("Первый вызов")
.thenReturn("Второй вызов")
.thenReturn("Третий вызов");
И действительно, меньше — значит лучше.
Борьба со статическими заглушками
Использование статических заглушек может привести к проблемам, так как они зачастую перенесут состояния тестов друг в друга, делая тесты уязвимыми.
Адаптация заглушек под различные тестовые сценарии
Разные тестовые сценарии могут требовать, чтобы заглушка вёл себя по-своему, что способствует повторному использованию кода и улучшает читаемость и восприятие тестов.
Сохранность тестирования
Важно, чтобы каждый тест был независимым и не оказывал влияния на другие тесты, используя свои уникальные настройки заглушек. Это является залогом воспроизводимости тестовых результатов.
Упрощение разработки и сокращение времени
Использование методов Mockito для создания цепочек может значительно сократить время, необходимое для настройки заглушек в тестах.
Полезные материалы
- Mockito-core 5.10.0 javadoc — подробное описание возможностей применения Answer в Mockito.
- Mockito (Mockito 3.2.4 API) — детальное руководство по последовательным вызовам в Mockito.
- Mockito-core 5.10.0 javadoc — исчерпывающее описание методов работы с when/thenReturn в Mockito.
- Руководство по JUnit 5 — подробный обзор использования Mockito в JUnit 5.
- Тестирование с Mockito – Уроки — пошаговое введение в создание и использование заглушек с помощью Mockito.