Карта / Тестирование / Виды заглушек (mock, stub, spy)

Виды заглушек (mock, stub, spy)

Заглушка (test double) — общее название для “поддельных” объектов в тестах. У них разные оттенки смысла, хотя на практике в Java чаще всего используют Mockito для всех трёх:

Stub — просто возвращает заранее заданные данные, без проверки, как его вызывали:

UserRepository stub = mock(UserRepository.class);
when(stub.findById(1)).thenReturn(new User(1, "Артур"));   // просто отвечает

Mock — то же самое, но дальше проверяется, как именно его вызывали:

verify(mockRepo).save(any());   // важно: был ли вызов, сколько раз, с какими аргументами

Spy — оборачивает реальный объект, и по умолчанию вызывает его настоящие методы, но позволяет подменить отдельные:

List<String> realList = new ArrayList<>();
List<String> spyList = spy(realList);
spyList.add("Артур");          // реально добавляется, как в обычном ArrayList
when(spyList.size()).thenReturn(100);   // а это поведение подменили
Копнуть глубже

Когда что выбрать:

ЗаглушкаКогда использовать
Stubпросто нужны тестовые данные, поведение вызовов не важно
Mockважно убедиться, что метод был вызван (например, что отправка письма реально произошла)
Spyнужен в основном реальный объект, но с парой подменённых методов

Главное правило. Не злоупотребляй проверками verify() — если тест проверяет каждый вызов, он становится хрупким: малейший рефакторинг внутренней реализации (даже без изменения результата) ломает тест. Проверяй через verify() только то, что действительно важно как побочный эффект — например, что письмо отправилось, а не как именно метод дошёл до этого.

🎤 Закрыл тему, если можешь объяснить:
• разницу между stub (просто данные) и mock (с проверкой вызовов);
• что такое spy и когда он удобнее обычного mock (если дошёл до 2-го слоя).