Использовал ли моки (Mock) в модульном тестировании?

Ответ

Да, активно использую моки для изоляции модуля, который тестирую, от его внешних зависимостей. Это позволяет писать быстрые, стабильные и сфокусированные unit-тесты.

Пример с Mockito в Java для тестирования сервиса, работающего с базой данных:

import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

@Test
void getUser_ShouldReturnUser_WhenUserExists() {
    // 1. Создаем мок репозитория (зависимость)
    UserRepository userRepositoryMock = mock(UserRepository.class);

    // 2. Задаем поведение мока: при вызове findById(1) возвращаем тестового пользователя
    User testUser = new User(1, "Иван Иванов");
    when(userRepositoryMock.findById(1L)).thenReturn(Optional.of(testUser));

    // 3. Внедряем мок в тестируемый сервис
    UserService userService = new UserService(userRepositoryMock);

    // 4. Вызываем метод сервиса
    User result = userService.getUserById(1L);

    // 5. Проверяем результат и факт взаимодействия с моком
    assertEquals("Иван Иванов", result.getName());
    verify(userRepositoryMock, times(1)).findById(1L); // Верификация: метод был вызван ровно 1 раз
}

Ключевые принципы, которых придерживаюсь:

  • Моки – для проверки взаимодействия (вызван ли метод, с какими аргументами). Использую, например, для проверки вызова логгера или отправки уведомления.
  • Стабы (Stubs) – для подмены состояния (возврата заранее заданных данных). Использую для эмуляции ответов от внешнего API или сложных вычислений.
  • Фейки (Fakes) – для замены тяжелой зависимости на упрощенную, но работающую реализацию (например, in-memory база данных вместо реальной).

Ответ 18+ 🔞

Слушай, а про моки-то я тебе расскажу, это вообще отдельная песня. Ну, то есть, я их активно юзаю, чтобы изолировать модуль, который тестирую, от всей его внешней хуйни — зависимостей там всяких. Это ж, ёпта, святое дело: тесты тогда быстрые, стабильные и сфокусированные, как лазер. Не надо ждать, пока база проснётся или API какой-нибудь сдохнет.

Вот, смотри, пример на Java с Mockito, чтобы было понятнее, о чём речь. Это как раз про тестирование сервиса, который с базой данных работает.

import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

@Test
void getUser_ShouldReturnUser_WhenUserExists() {
    // 1. Создаем мок репозитория (зависимость)
    UserRepository userRepositoryMock = mock(UserRepository.class);

    // 2. Задаем поведение мока: при вызове findById(1) возвращаем тестового пользователя
    User testUser = new User(1, "Иван Иванов");
    when(userRepositoryMock.findById(1L)).thenReturn(Optional.of(testUser));

    // 3. Внедряем мок в тестируемый сервис
    UserService userService = new UserService(userRepositoryMock);

    // 4. Вызываем метод сервиса
    User result = userService.getUserById(1L);

    // 5. Проверяем результат и факт взаимодействия с моком
    assertEquals("Иван Иванов", result.getName());
    verify(userRepositoryMock, times(1)).findById(1L); // Верификация: метод был вызван ровно 1 раз
}

Видишь, какая красота? Никакой реальной базы, просто кукла, которая делает то, что мы скажем. Ёперный театр, а не подход.

А теперь, чтобы не превратиться в распиздая, который всё подряд мокает бездумно, есть ключевые принципы, которых я держусь. Это как заповеди, блядь.

  • Моки – это когда мне похуй на результат, но важно взаимодействие. Вызвал ли метод? С какими аргументами? Вот это вот всё. Идеально, чтобы проверить, отправилось ли уведомление или вызвался логгер. Доверия ебать ноль к внешнему миру, поэтому проверяю факт рукопожатия.
  • Стабы (Stubs) – тут уже про состояние. Мне нужно, чтобы зависимость вернула конкретные данные, и всё. Например, эмулирую ответ от какого-нибудь внешнего API, который в тестах может быть нестабильным, как хитрая жопа. Просто подменяю его поведение на предсказуемое.
  • Фейки (Fakes) – это уже серьёзнее. Когда зависимость слишком тяжёлая (та же база), но мне нужна хоть какая-то работающая логика. Тогда пишу её упрощённую, но честную реализацию — типа in-memory базы данных. Это уже не просто кукла, а манекен, который умеет ходить. Главное — не настолько охуеть от процесса, чтобы фейк стал сложнее продакшн-кода.

Вот так-то, чувак. Без этого — пиздец, а не тесты, одни мучения.