Виды заглушек (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() только то, что действительно важно как побочный эффект — например, что письмо отправилось, а не как именно метод дошёл до этого.
• что такое spy и когда он удобнее обычного mock (если дошёл до 2-го слоя).