从导入的包中模拟函数时,pytest 模拟失败

问题描述 投票:0回答:1

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 没有被嘲笑。我做错了什么吗?

python unit-testing mocking pytest pytest-mock
1个回答
0
投票

与导入的模块/包不同,

get_a
是一个普通的标识符,它指向您想要修补的函数,而无需在
mypackage.mymodule
中查找它,因为这在导入期间已经完成了。因此,在这种情况下,您必须像第一次测试一样直接通过
f"{__name__}.get_a"
修补它。这不是
pytest-mock
的特殊行为。

© www.soinside.com 2019 - 2024. All rights reserved.