mock.patch退出with语句后模拟对象未失效问题咨询
问题原因:patch目标路径错误
你的问题本质是没有patch到被测试代码实际使用的Math类引用,导致补丁的撤销逻辑没有作用到calculation.py的执行上下文里。
具体原因拆解
假设你的代码结构如下:
math.py:
class Math: def addition(self, a, b): return a + b
calculation.py:
# 这里是关键:直接导入Math类到当前命名空间 from math import Math def perform_addition(a, b): return Math().addition(a, b)
test_sample.py:
from unittest.mock import patch from calculation import perform_addition # 错误的patch路径:patch的是原模块的Math with patch("math.Math") as mock_math: mock_math.return_value.addition.return_value = 100 print(perform_addition(1,2)) # 输出100 print(perform_addition(1,2)) # 依然输出100
当calculation.py执行from math import Math时,会把math.Math的引用复制到自己的模块命名空间中。此时你patchmath.Math,只会替换math模块里的Math引用,但calculation模块里已经保存的Math引用不会被更新——也就是说,calculation里的Math已经变成了mock对象,且这个引用不会被with语句的撤销逻辑影响,因为patch的目标不是它。
解决方法
把patch的目标改成calculation模块里的Math引用:
from unittest.mock import patch from calculation import perform_addition # 正确的patch路径:patch被测试代码实际使用的Math引用 with patch("calculation.Math") as mock_math: mock_math.return_value.addition.return_value = 100 print(perform_addition(1,2)) # 输出100 print(perform_addition(1,2)) # 输出3,符合预期
核心规则
记住:patch的目标必须是被测试代码实际导入并使用的那个对象的路径,而不是原对象的定义路径。如果被测试代码用from X import Y导入,就patchmodule.Y;如果用import X然后用X.Y,就patchX.Y。
内容的提问来源于stack exchange,提问作者Aditya Bangard
相关产品推荐
相关产品推荐

