You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:16:11