Что такое аннотация @Spy в Mockito и для чего она используется?

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

Ответ

@Spy — это аннотация фреймворка Mockito для создания частичного мока (spy) реального объекта.

Принцип работы:

  • Создается обертка вокруг реального экземпляра класса.
  • По умолчанию все методы вызываются у реального объекта.
  • Вы можете замокать (stub) конкретные методы spy-объекта, чтобы изменить их поведение для теста, оставив остальные методы работающими как есть.

Зачем использовать:

  • Когда нужно протестировать взаимодействие с реальным объектом, но подменить один или несколько его методов.
  • Полезно для тестирования legacy-кода, где сложно выделить зависимости для полного мока.

Пример:

@Spy
private List<String> spyList = new ArrayList<>();

@Test
public void testSpy() {
    // Реальный метод работает
    spyList.add("real");
    // Замокали один метод
    doReturn(100).when(spyList).size();

    assertEquals("real", spyList.get(0)); // Вызов реального метода
    assertEquals(100, spyList.size());     // Вызов замоканного метода
}

Важно: Для мока void-методов или методов, где нужно выбросить исключение, используйте doReturn(), doThrow(), doAnswer(), а не when(...).thenReturn() на spy-объекте, чтобы избежать вызова реального метода.