Что такое Spy в контексте модульного тестирования?

«Что такое Spy в контексте модульного тестирования?» — вопрос из категории Тестирование, который задают на 22% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Spy (шпион) — это тип тестового двойника (test double), который оборачивает реальный объект, перехватывая и записывая вызовы его методов, но по умолчанию делегируя выполнение оригинальной реализации.

Ключевые отличия от Mock:

  • Mock — полностью заглушенный объект, где поведение всех методов нужно задавать явно.
  • Spy — работает с реальным объектом, позволяя верифицировать вызовы и при необходимости подменять поведение только конкретных методов.

Пример использования Spy в Mockito (Java):

// Создаём реальный объект ArrayList
List<String> realList = new ArrayList<>();

// Создаём шпиона на его основе
List<String> spiedList = Mockito.spy(realList);

// Вызываем методы. Реальная логика выполняется.
spiedList.add("first");
spiedList.add("second");

// Верифицируем, что метод add("first") был вызван
Mockito.verify(spiedList).add("first");

// Проверяем реальное состояние объекта
assertEquals(2, spiedList.size()); // true

// Можно подменить поведение одного метода, оставив остальные реальными
Mockito.when(spiedList.size()).thenReturn(100);
assertEquals(100, spiedList.size()); // теперь вернёт 100

Когда использовать: Когда нужно протестировать взаимодействие с объектом, но при этом важно сохранить его основное рабочее поведение.