Ответ
Хотя оба инструмента используются для подготовки тестового окружения, у них принципиально разные цели:
-
Mock (Мок) — это объект-заглушка, который заменяет (подменяет) реальную зависимость (например, модуль, класс, функцию) для изоляции тестируемого кода. Это позволяет тестировать компонент, не затрагивая его внешние зависимости (API, базу данных, файловую систему).
-
Fixture (Фикстура) — это функция, которая предоставляет данные, объекты или настраивает состояние для тестов. Она используется для подготовки окружения и устранения дублирования кода (принцип DRY — Don't Repeat Yourself).
Сравнение:
Аспект | Mock | Fixture |
---|---|---|
Основная цель | Изоляция кода, имитация поведения | Подготовка данных и состояния, переиспользование кода |
Что делает? | Подменяет реальный объект | Предоставляет готовый объект или данные |
Источник | unittest.mock или pytest-mock (обертка mocker ) |
Декоратор @pytest.fixture |
Пример | Заменить обращение к внешнему API на возврат заранее заданного JSON | Создать подключение к тестовой БД или вернуть объект пользователя |
Пример совместного использования
Представим, что у нас есть функция, которая получает данные пользователя из БД и возвращает его возраст.
import pytest
# ФИКСТУРА: предоставляет тестовые данные
@pytest.fixture
def sample_user_data():
"""Эта фикстура просто возвращает словарь с данными."""
return {"id": 1, "name": "Alice", "age": 30}
# Функция, которую мы хотим протестировать
# (предполагается, что db.get_user обращается к реальной БД)
from my_app import logic, db
def test_get_user_age(mocker, sample_user_data):
# МОК: подменяем функцию обращения к БД
# Теперь при вызове db.get_user(1) не будет реального запроса к БД,
# а вернется значение из фикстуры sample_user_data.
mocker.patch('my_app.db.get_user', return_value=sample_user_data)
# Вызываем тестируемую логику
age = logic.get_user_age(1)
# Проверяем, что наша логика правильно извлекла возраст
assert age == 30
В этом примере:
- Фикстура
sample_user_data
подготовила нам тестовые данные. - Мок
mocker.patch
изолировал тест от реальной базы данных, заставив функциюdb.get_user
вернуть наши данные.