Ответ
Mock-объекты (моки) — это "поддельные" объекты, которые имитируют поведение реальных зависимостей в контролируемых условиях. Они являются ключевым инструментом для изоляции тестируемого компонента.
Основная цель их использования — заменить внешние зависимости (например, базу данных, внешнее API, файловую систему), чтобы:
- Изолировать тест: Убедиться, что тест проверяет только логику конкретного модуля, а не его зависимостей.
- Ускорить выполнение тестов: Избежать медленных операций, таких как сетевые запросы или чтение с диска.
- Сделать тесты детерминированными: Контролировать возвращаемые значения и ошибки, делая результат теста предсказуемым.
- Тестировать сложные сценарии: Эмулировать специфические состояния или ошибки, которые трудно воспроизвести с реальными объектами (например, отказ сети).
Пример с unittest.mock
в Python:
Предположим, у нас есть функция, которая получает данные о погоде с внешнего API.
import requests
def get_weather_forecast():
response = requests.get("http://api.weather.com/forecast")
response.raise_for_status() # Вызовет исключение для плохих статусов
return response.json()["temperature"]
Тест с использованием patch
для подмены requests.get
:
from unittest.mock import patch
def test_get_weather_forecast_success():
# Создаем mock-объект для ответа API
mock_response = {"temperature": 25}
# patch заменяет requests.get на mock-объект внутри блока with
with patch('requests.get') as mock_get:
# Настраиваем, что должен вернуть наш mock
mock_get.return_value.json.return_value = mock_response
mock_get.return_value.raise_for_status.return_value = None
# Вызываем нашу функцию
temperature = get_weather_forecast()
# Проверяем результат
assert temperature == 25
# Проверяем, что requests.get был вызван с правильным URL
mock_get.assert_called_once_with("http://api.weather.com/forecast")
Ключевые инструменты в Python:
unittest.mock
: Стандартная библиотека для мокинга.pytest-mock
: Популярный плагин дляpytest
, предоставляющий удобную фикстуруmocker
.