Менеджер контекста патча pytest-mock не восстанавливает объект при выходе
Недавно мы перешли с unittest на pytest. Я столкнулся со странной проблемой при использованииmocker.patch
как менеджер контекста. Рассмотрим следующий пример.
module_a.py
class MyClass:
def value(self):
return 10
module_b.py
import module_a
class AnotherClass:
def get_value(self):
return module_a.MyClass().value()
test_module_b.py
from module_b import AnotherClass
def test_main_2(mocker):
with mocker.patch('module_a.MyClass.value', return_value=20):
value = AnotherClass().get_value()
assert value == 20
value = AnotherClass().get_value()
assert value == 10
Я ожидал, что после выхода из диспетчера контекста метод метода значения MyClass будет восстановлен (возвращаемое значение 10), однако тест не проходит во втором утверждении утверждения с ошибкой утверждения. 20 != 10
Если я использую тот же тест, но заменю mocker.patch
с unittest.mock.patch
, это проходит. Я думал, что pytest-mock использует тот же API, что и unittest.mock, поэтому я не понимаю, почему есть разница.
1 ответ
С pytest-mock
, разрыв выполняется при выходе из контекста фикстуры. Вmocker.patch
объект - это не просто псевдоним для mock.patch
.
Вам не нужны диспетчеры контекста в тестовых функциях при написании тестов в стиле pytest, и на самом деле цель плагина pytest-mock состоит в том, чтобы использовать диспетчеры контекста и декораторы функций для ненужного имитации.
Если по какой - то причине вам нужно сделать шаг Teardown из внутри самого теста, то вы хотите простой старый макет API, который прекрасно работает в pytest.
from unittest.mock import patch
def test_main_2():
with patch('module_a.MyClass.value', return_value=20):
value = AnotherClass().get_value()
assert value == 20
value = AnotherClass().get_value()
assert value == 10
Имейте в виду, что эта вложенная структура - это действительно то, чего pytest намеревается избегать, чтобы ваши тесты были более читабельными, поэтому вы несколько упускаете суть, если не выполняете настройку и разборку полностью с помощью фикстур.