Python测试含全局变量的方法时无法覆盖变量值的问题
问题:无法通过unittest.mock.patch覆盖Python全局变量的值
我正在测试一个使用全局设置变量的Python方法,涉及以下3个文件:
setting_to_test.py:
import os GLOBAL_VAR = os.environ.get("GLOBAL_VAR", 6)
function_to_test.py:
from setting_to_test import GLOBAL_VAR def funca(): return GLOBAL_VAR ** 2
test_module.py:
from unittest.mock import patch from function_to_test import funca @patch("setting_to_test.GLOBAL_VAR", 66) def test_my_module(): assert funca() == 66 ** 2
我希望将全局变量的默认值(6)覆盖为66,但无论尝试什么,变量值始终为6。使用PyCharm运行测试的命令如下:
"C:\Program Files\JetBrains\PyCharm 2021.3.2\plugins\python\helpers\pycharm\_jb_pytest_runner.py" --path C:/myfolder/code/testing_project/test_module.py
解决方案
问题出在patch的目标路径错误。当function_to_test.py执行from setting_to_test import GLOBAL_VAR时,会把GLOBAL_VAR的值复制到自身的命名空间中,后续funca()调用的是这个副本,而非setting_to_test.py里的原变量。你当前patch的是setting_to_test.GLOBAL_VAR,但这不会影响function_to_test已经导入的副本。
方法1:修改patch的目标路径
直接patchfunction_to_test命名空间中的GLOBAL_VAR,这是被测试代码实际引用的变量:
修改后的test_module.py:
from unittest.mock import patch from function_to_test import funca @patch("function_to_test.GLOBAL_VAR", 66) def test_my_module(): assert funca() == 66 ** 2
方法2:调整导入方式(从根源避免问题)
修改function_to_test.py,改为导入整个模块再访问变量,这样每次调用funca()都会读取原模块的最新值:
import setting_to_test def funca(): return setting_to_test.GLOBAL_VAR ** 2
此时你原来的patch代码(@patch("setting_to_test.GLOBAL_VAR", 66))就能正常生效。
内容的提问来源于stack exchange,提问作者Netanel
相关产品推荐
相关产品推荐

