← Назад к вопросам

В чем разница между stub и mock?

2.0 Middle🔥 202 комментариев
#Автоматизация тестирования#Тестирование

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между Stub и Mock в тестировании

В контексте модульного тестирования и тестовой изоляции, stub и mock являются двумя важнейшими типами тестовых двойников (test doubles), но они служат разным целям и используются в разных сценариях. Оба помогают изолировать тестируемый код от зависимостей, но принципиально отличаются по своему поведению и назначению.

Ключевое концептуальное отличие

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

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

Детальное сравнение

Stub: Предоставление данных

  • Пассивный объект: просто возвращает жестко заданные значения
  • Фокус на состоянии: помогает установить необходимое состояние для теста
  • Нет проверки вызовов: не следит за тем, как и сколько раз его методы вызываются
  • Простая реализация: обычно создается вручную или с помощью минимальных средств фреймворка

Пример stub на Python:

class UserRepositoryStub:
    """Stub для репозитория пользователей"""
    def get_user(self, user_id):
        # Всегда возвращает предопределенного пользователя
        return User(id=user_id, name="Test User", email="test@example.com")
    
    def is_user_active(self, user_id):
        # Всегда возвращает True для упрощения теста
        return True

# В тесте
def test_user_greeting():
    repo = UserRepositoryStub()
    service = UserService(repo)
    result = service.get_greeting(123)
    assert result == "Hello, Test User!"

Mock: Проверка взаимодействий

  • Активный объект: ожидает определенных вызовов и проверяет их
  • Фокус на поведении: проверяет, как тестируемый код взаимодействует с зависимостями
  • Верификация вызовов: явно проверяет, какие методы были вызваны, с какими параметрами
  • Использование фреймворков: обычно создается с помощью библиотек (unittest.mock, Moq, Mockito)

Пример mock на Python с unittest.mock:

from unittest.mock import Mock

def test_send_notification():
    """Тест проверяет, что сервис правильно вызывает отправку уведомления"""
    # Создаем mock для сервиса уведомлений
    notification_mock = Mock()
    notification_mock.send_email.return_value = True
    
    # Внедряем mock в тестируемый сервис
    user_service = UserService(notification_mock)
    user_service.notify_user(123, "Welcome message")
    
    # ВЕРИФИКАЦИЯ: проверяем, что метод был вызван правильно
    notification_mock.send_email.assert_called_once_with(
        user_id=123,
        message="Welcome message",
        subject="Notification"
    )

Практические различия в использовании

Когда использовать Stub:

  • Нужно предоставить тестовые данные для зависимостей
  • Требуется симулировать определенное состояние системы
  • Зависимость возвращает значения, но их вызов не является частью Assert
  • Тестируемый код только получает данные от зависимости

Когда использовать Mock:

  • Необходимо проверить, что тестируемый код правильно вызывает методы зависимости
  • Нужно убедиться в определенной последовательности вызовов
  • Требуется проверить количество вызовов методов
  • Важно убедиться, что методы вызываются с правильными параметрами

Сравнительная таблица

АспектStubMock
Основная цельПредоставление данныхПроверка взаимодействий
Проверка вызововНетДа (критически важно)
СложностьПростаяБолее сложная
Использование в AssertДля проверки возвращаемых значенийДля проверки вызовов методов
Тип тестированияСостояния (state-based)Взаимодействия (interaction-based)

Смешанные сценарии и современные подходы

На практике часто используются гибридные подходы:

  • Spy (шпион) — частичный mock, который может вести себя как stub, но при этом отслеживает вызовы
  • Fake (фейк) — упрощенная рабочая реализация зависимости (например, in-memory база данных)

В современных фреймворках границы иногда размыты, и один объект может выполнять обе роли, но концептуальное различие остается важным для написания чистых, понятных и целенаправленных тестов.

Вывод

Основное различие можно сформулировать так: stub помогает тесту запуститься, предоставляя необходимые данные, а mock проверяет, что тестируемый код правильно взаимодействует со своими зависимостями. Понимание этой разницы позволяет выбирать правильный инструмент для конкретной задачи тестирования, что ведет к более поддерживаемым и надежным тестам. Stub отвечает на вопрос "что", а mock — на вопрос "как".

В чем разница между stub и mock? | PrepBro