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

mock.patch退出with语句后模拟对象未失效问题咨询

问题原因:patch目标路径错误

你的问题本质是没有patch到被测试代码实际使用的Math类引用,导致补丁的撤销逻辑没有作用到calculation.py的执行上下文里。

具体原因拆解

假设你的代码结构如下:

  1. math.py:
class Math:
    def addition(self, a, b):
        return a + b
  1. calculation.py:
# 这里是关键:直接导入Math类到当前命名空间
from math import Math

def perform_addition(a, b):
    return Math().addition(a, b)
  1. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:23:15