ПРИХОДИТЕ УЧИТЬСЯ НОВОЙ ПРОФЕССИИ ЛЕТОМ СО СКИДКОЙ ДО 70%Забронировать скидку
logo

Меняем возвращаемые значения в Mockito без ребилда моков

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

С помощью библиотеки Mockito можно настроить поведение методов объекта-заглушки так, чтобы они возвращали разные значения при каждом новом вызове. Вам обязательно пригодятся в этом случае множественные вызовы метода thenReturn:

Java
Скопировать код
SomeClass mock = mock(SomeClass.class);
when(mock.method()).thenReturn("Первый").thenReturn("Второй");

System.out.println(mock.method()); // Вывод на экран "Первый"
System.out.println(mock.method()); // Вывод на экран "Второй"

При первом вызове метод method() вернёт "Первый", а при повторном вызове — "Второй".

Загадочный мир Mockito: уникальные значения, исключения и удивление

Последовательное возвращение уникальных значений

Метод thenReturn принимает аргументы переменной длины (varargs), что позволяет настроить последовательность возвращаемых значений:

Java
Скопировать код
when(mock.method()).thenReturn("Первый вызов", "Второй вызов", "Халк разрушает!", "Четвертый вызов");

Таким образом, при каждом вызове будет возвращаться следующее значение из указанной последовательности. Фраза "Халк разрушает!" в последовательности для создания элемента неожиданности.

Имитация генерации исключений при помощи заглушек

Различные ситуации в процессе тестирования могут потребовать генерацию исключений. Для этого можно воспользоваться сочетанием методов thenReturn и thenThrow:

Java
Скопировать код
when(mock.method()).thenReturn("Хорошие времена").thenThrow(new RuntimeException());

Итак, при первом вызове метода вас ждут "Хорошие времена", но все последующие вызовы приведут к возникновению исключений.

Важность сброса состояния заглушек перед каждым тестом

Чтобы избежать влияния предыдущих тестов на следующие, рекомендуется сбрасывать состояние заглушек перед каждым тестом:

Java
Скопировать код
@Before
public void setup() {
    reset(mock);
    // Настройка заглушки перед следующим тестом
}

Данная практика обеспечивает "чистый" старт каждого теста.

Исключение реальных вызовов при работе с шпионами в Mockito

При работе с шпионами рекомендуется использовать doReturn() вместо when(), чтобы предотвратить реальные вызовы методов:

Java
Скопировать код
SomeClass spy = spy(new SomeClass());
doReturn("Контролируемый ответ").when(spy).method();

Таким образом, мы подменяем реальное поведение, не позволяя приложению выполнять настоящие действия.

Направление на создание изолированной тестовой среды

При прохождении каждого теста полезно создавать отдельные экземпляры заглушек, что можно выполнить в блоке @Before:

Java
Скопировать код
private SomeClass mock;

@Before
public void setup() {
    mock = mock(SomeClass.class);
    // Настройка тестовой среды
}

Определение одной заглушки на каждый тест обеспечивает изоляцию тестов друг от друга.

Визуализация

Представьте себе вокзал с поездами (🚆), где каждый поезд — это уникальный вызов метода.

Первый вызов 🚆: Возвращает "📚"
Второй вызов 🚆: Возвращает "🎮"
Третий вызов 🚆: Возвращает "🏈"

Теперь, когда мы применяем Mockito, это можно представить как диалог с диспетчером:

Java
Скопировать код
mock.when(station.nextTrainArrives())
    .thenReturn("📚")
    .thenReturn("🎮")
    .thenReturn("🏈");

В результате каждый вызов будет представлять собой уникальную грузоперевозку, в форме символической последовательности "📚🎮🏈".

Искусство работы с Mockito: Позитивные моменты, Трудности и Лучшие практики

Повышение читаемости кода при помощи цепных вызовов

Цепочечные вызовы методов упрощают код, естественным образом повышая его читаемость и помогая уменьшить объём кода:

Java
Скопировать код
when(mock.method())
    .thenReturn("Первый вызов")
    .thenReturn("Второй вызов")
    .thenReturn("Третий вызов");

И действительно, меньше — значит лучше.

Борьба со статическими заглушками

Использование статических заглушек может привести к проблемам, так как они зачастую перенесут состояния тестов друг в друга, делая тесты уязвимыми.

Адаптация заглушек под различные тестовые сценарии

Разные тестовые сценарии могут требовать, чтобы заглушка вёл себя по-своему, что способствует повторному использованию кода и улучшает читаемость и восприятие тестов.

Сохранность тестирования

Важно, чтобы каждый тест был независимым и не оказывал влияния на другие тесты, используя свои уникальные настройки заглушек. Это является залогом воспроизводимости тестовых результатов.

Упрощение разработки и сокращение времени

Использование методов Mockito для создания цепочек может значительно сократить время, необходимое для настройки заглушек в тестах.

Полезные материалы

  1. Mockito-core 5.10.0 javadoc — подробное описание возможностей применения Answer в Mockito.
  2. Mockito (Mockito 3.2.4 API) — детальное руководство по последовательным вызовам в Mockito.
  3. Mockito-core 5.10.0 javadoc — исчерпывающее описание методов работы с when/thenReturn в Mockito.
  4. Руководство по JUnit 5 — подробный обзор использования Mockito в JUnit 5.
  5. Тестирование с Mockito – Уроки — пошаговое введение в создание и использование заглушек с помощью Mockito.