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

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

Ответ

Mock (Мок-объект) — это тестовый двойник, который имитирует поведение реальной зависимости, позволяя изолировать тестируемый модуль и проверять его взаимодействие с этой зависимостью.

Основное назначение:

  1. Изоляция: Замена внешних сервисов (БД, API, файловой системы).
  2. Верификация: Проверка, что тестируемый код корректно вызывает методы зависимости с ожидаемыми аргументами.
  3. Задание поведения: Определение ответов на вызовы методов (возврат значений, выброс исключений).

Пример с Mockito (Java):

// Зависимость
public class PaymentGateway {
    public boolean charge(double amount) { /* ... */ }
}

// Тест
@Test
public void orderService_ShouldChargeCustomer() {
    // 1. Создание мока
    PaymentGateway mockGateway = Mockito.mock(PaymentGateway.class);
    // 2. Задание поведения
    Mockito.when(mockGateway.charge(100.0)).thenReturn(true);

    // 3. Использование мока в тестируемом сервисе
    OrderService service = new OrderService(mockGateway);
    boolean success = service.placeOrder(100.0);

    // 4. Проверка состояния и взаимодействия
    assertTrue(success);
    Mockito.verify(mockGateway).charge(100.0); // Верификация вызова
}

Отличие от других тестовых двойников:

  • Stub (Заглушка): Пассивный объект, только возвращает предопределённые данные.
  • Spy (Шпион): Обёртка над реальным объектом, позволяющая отслеживать вызовы и при необходимости подменять поведение.
  • Mock (Мок): Активно используется для верификации взаимодействий.