pytest 模拟导入包中的函数时失败
pytest-mock 已经正确安装:
> pip list | grep pytest
pytest 7.4.2
pytest-mock 3.14.0
这个单元测试成功通过了:
import pytest
class A:
def __init__(self, value):
self.value = value
def get_a() -> A:
return A(1)
@pytest.fixture
def mocked_A(mocker):
a = A(2)
mocker.patch(f"{__name__}.get_a", return_value=a)
def test_mocked_a(mocked_A) -> None:
a = get_a()
assert a.value == 2
现在,如果我把 A 和 get_A 移到 mypackage.mymodule 里,模拟就不再有效了。
import pytest
# note: these imports work: mypackage is correctly installed
from mypackage.mymodule import A, get_a
@pytest.fixture
def mocked_A(mocker):
a = A(2)
mocker.patch("mypackage.mymodule.get_a", return_value=a)
def test_mocked_a(mocked_A) -> None:
a = get_a()
assert a.value == 2
测试失败,出现了这个错误:
mocked_A = None
def test_mocked_a(mocked_A) -> None:
a = get_a()
> assert a.value == 2
E assert 1 == 2
E + where 1 = <mypackage.mymodule.A object at 0x7f063e3f2c80>.value
test_a.py:13: AssertionError
=============================================================================== short test summary info ================================================================================
FAILED test_a.py::test_mocked_a - assert 1 == 2
看起来 get_a 没有被模拟。请问我做错了什么吗?
1 个回答
1
和导入的模块或包不同,get_a
只是一个普通的标识符,它指向你想要修改的函数,而不需要在mypackage.mymodule
中查找,因为这个查找在导入时已经完成了。所以在这种情况下,你需要直接通过f"{__name__}.get_a"
来修改,就像你第一次测试时那样。这并不是pytest-mock
的特殊行为。