Менеджер контекста патча 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 намеревается избегать, чтобы ваши тесты были более читабельными, поэтому вы несколько упускаете суть, если не выполняете настройку и разборку полностью с помощью фикстур.

Другие вопросы по тегам