如何Mock常量值?为何patch __init__.py中常量未生效?
pytest-mock打补丁__init__.py常量未生效的原因及解决方法
项目结构
mod1 ├── mod2 │ ├── __init__.py │ └── utils.py └── tests └── test_utils.py
各文件内容:
mod1/mod2/__init__.py:
CONST = -1
mod1/mod2/utils.py:
from mod1.mod2 import CONST def mod_function(): print(CONST)
mod1/tests/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()
为什么补丁没生效?
你在utils.py里用from mod1.mod2 import CONST的导入方式,会把CONST的当前值(-1)直接复制到utils模块的命名空间中,而非建立对原模块mod1.mod2中CONST的动态引用。此时你打补丁修改mod1.mod2.CONST,utils里调用的还是之前复制过来的-1,自然不会输出预期的1000。
正确打补丁的两种方法
方法一:修改导入方式,保留引用关系
把utils.py的导入改成直接引用原模块的形式:
import mod1.mod2 def mod_function(): print(mod1.mod2.CONST)
此时原测试代码无需修改,运行测试就会输出1000——因为mod_function现在直接调用mod1.mod2里的CONST,补丁能直接作用到目标上。
方法二:直接打补丁utils模块内的CONST
如果不想改动业务代码,就直接针对utils模块中已经导入的CONST副本打补丁:
修改test_utils.py的补丁路径:
from mod1.mod2.utils import mod_function def test_mod_function(mocker): # 补丁目标改为utils模块内的CONST mocker.patch("mod1.mod2.utils.CONST", 1000) mod_function()
运行测试后会输出1000,因为补丁直接修改了utils命名空间里的CONST值。
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

