✔️ Тест прошёл, но не потому что мок сработал — 24 июня 2026 г. в 18:02:50.496
✔️ Тест прошёл, но не потому что мок сработал Классическая ловушка с моками в Python: тест зелёный, но реальный API всё равно вызывается. Вот как это происходит и как проверить что мок реально перехватил вызов. Симптом Тест на исключение при невалидной валюте проходит. Но в моке настроен ответ "result": "success" — который никогда не выбросит исключение. Как тест зелёный? Реальный API вернул ошибку для несуществующей валюты «CTM». Мок вообще не сработал. Как доказать что мок перехватил вызов with pytest.raises(CurrencyConversionError): convert_currency( amount=Decimal("1.00"), from_currency="CAD", to_currency="CTM", ) mock_get.assert_called_once() # если упал — мок не перехватил, бил реальный API assert_called_once() — не опциональная проверка, а обязательная часть теста когда вы мокаете внешние вызовы. Главное правило: патчить там где имя используется, не где определено # модуль делает: import requests # правильно: mocker.patch("myapp.utils.currency.requests.get") # если модуль делает: from requests import get # то только так: mocker.patch("myapp.utils.currency.get") # requests.get здесь не перехватит ничего Это самая частая причина почему мок «не работает». Итоговый тест с pytest-mock def test_bad_currency_raises(self, mocker): mock_get = mocker.patch("myapp.utils.currency.requests.get") mock_get.return_value.json.return_value = { "result": "error", "error-type": "unknown-code", } with pytest.raises(CurrencyConversionError): convert_currency(Decimal("1.00"), "CAD", "CTM") mock_get.assert_called_once() Когда мок — не лучший инструмент Если каждый тест завязан на конкретный import path — это тест реализации, не поведения. Альтернатива: адаптер-класс для внешнего вызова + fake-реализация + dependency injection. Тогда не нужно патчить вообще.

