Урок курса
Monkeypatch и mock в pytest: когда что применять
Python для продвинутых: ООП, типизация и тестированиеТест должен контролировать нестабильные зависимости: текущее время, случайность, переменные окружения и сетевые клиенты. Fixture monkeypatch временно меняет атрибут, словарь, окружение или текущую директорию и автоматически возвращает состояние после теста.
def test_mode_from_env(monkeypatch):
monkeypatch.setenv("APP_MODE", "test")
assert read_mode() == "test"
Для объекта можно использовать monkeypatch.setattr(module, "name", replacement). Подменять нужно имя там, где код его ищет, а не обязательно там, где функция была определена изначально. Это частая причина «mock не сработал».
unittest.mock и проверка взаимодействий
Mock и patch умеют задавать возвращаемое значение, выбрасывать исключение и проверять вызовы.
from unittest.mock import Mock
sender = Mock()
sender.send.return_value = "msg-1"
service = NotificationService(sender)
service.notify("hello")
sender.send.assert_called_once_with("hello")
Если интерфейс известен, используйте spec или autospec: тогда опечатка в методе mock не пройдёт незаметно. Для простой зависимости собственный маленький fake или stub часто читается лучше универсального Mock.
Не тестируйте реализацию вместо поведения
Проверка каждого внутреннего вызова делает тест хрупким: безопасный рефакторинг ломает его, хотя внешний результат не изменился. Проверяйте взаимодействие, когда оно и есть контракт — например, платёж отправляется ровно один раз или письмо не уходит при ошибке валидации.
Не допускайте реальную сеть в unit-тестах. Однако бесконечные моки тоже опасны: они подтверждают согласованность теста с собственной фантазией, а не с API провайдера. Дополняйте их контрактными или интеграционными тестами на контролируемой среде.
Короткое правило: monkeypatch удобен для временной замены состояния и имён; Mock — для программируемого collaborator и assertions о вызовах; fake — для более реалистичного поведения без внешнего сервиса.
Попробуйте решить
Где следует patch-ить импортированную функцию?
Продолжить с проверкой и прогрессом
Откройте интерактивный раннер с заданиями урока.
