我有这样的结构:
mod1
├── mod2
│ ├── __init__.py
│ └── utils.py
└── tests
└── test_utils.py
哪里
__init__.py
:CONST = -1
utils.py
:from mod1.mod2 import CONST
def mod_function():
print(CONST)
test_utils.py
:from mod1.mod2.utils import mod_function
def test_mod_function(mocker):
mock = mocker.patch("mod1.mod2.CONST")
mock.return_value = 1000
mod_function()
pytest
和 mocker
。
通过运行
python -m pytest -s ./mod1/tests
,我希望看到 1000
作为输出,但得到了 -1
。为什么?
如何从
__init__.py
文件中修补常量?
patch("mod1.mod2.CONST")
所做的实际上是将模块对象 CONST
的 mod1.mod2
属性设置为不同的对象。它不会影响引用原始 mod1.mod2.CONST
对象的任何现有名称。
当
utils.py
这样做时:
from mod1.mod2 import CONST
它在
CONST
模块的命名空间中创建一个名称 mod1.mod2.utils
,引用当前由 -1
名称引用的对象 mod1.mod2.CONST
。
当
test_mod_function
这样做时:
mock = mocker.patch("mod1.mod2.CONST")
它修改
mod1.mod2
,使其 CONST
属性现在引用 Mock
对象,而 CONST
中的 mod1.mod2.utils
名称继续引用对象 -1
,这就是为什么设置 mock.return_value
不影响mod_function
的结果。
要使用模拟
mod_function
正确测试 CONST
,您可以在定义 CONST
的命名空间中修补 mod_function
:
mock = mocker.patch("mod1.mod2.utils.CONST")
或者您可以推迟导入
mod1.mod2.utils
,直到 mod1.mod2.CONST
已修补:
def test_mod_function(mocker):
mock = mocker.patch("mod1.mod2.CONST")
mock.return_value = 1000
from mod1.mod2.utils import mod_function
mod_function()