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

使用Python Mock Patch测试类未生效,求排查问题原因

问题分析与解决方案

你遇到的是mock/patch中非常典型的路径引用陷阱,核心原因是没搞清楚patch的作用对象:patch替换的是代码实际使用的那个对象引用,而非你随便指定的某个路径。

为什么你的代码没生效?

当你在test.py里执行from lib.inventory import Inventory时,相当于把lib.inventory模块里的Inventory类复制了一份到test模块的命名空间里。而你用@patch('lib.inventory.Inventory')替换的只是lib.inventory模块里的那个Inventory引用,但test模块里的Inventory还是指向原来的类,所以打印时会出现原类和Mock对象分离的情况。

两种可行的修复方案

方案1:patch测试模块里的Inventory引用

既然你的测试代码直接使用的是test模块里的Inventory,那直接patch这个位置即可:

import unittest
from mock import patch
import time
from lib.inventory import Inventory

class MyTest(unittest.TestCase):
    # 把patch目标改成test模块里的Inventory
    @patch('test.Inventory')
    def test_retrieve_project_id(self,mock_inventory):
        print("####################")
        print(Inventory)  # 现在会输出MagicMock对象
        print(mock_inventory)
        print("####################")

方案2:通过模块引用使用Inventory

修改测试代码的导入方式,直接引用lib.inventory模块里的Inventory,这样patchlib.inventory.Inventory就会生效:

import unittest
from mock import patch
import time
from lib import inventory  # 导入整个模块

class MyTest(unittest.TestCase):
    @patch('lib.inventory.Inventory')
    def test_retrieve_project_id(self,mock_inventory):
        print("####################")
        print(inventory.Inventory)  # 使用模块内的引用,会被patch替换
        print(mock_inventory)
        print("####################")

关键概念总结

记住mock/patch的核心原则:patch where the object is used, not where it's defined(patch对象被使用的位置,而非被定义的位置)。如果你的代码(测试或被测试逻辑)是通过from X import Y导入的,那Y的引用在当前模块里,这时候要patch当前模块的Y;如果是通过import X然后用X.Y,那patchX.Y就可以。

内容的提问来源于stack exchange,提问作者dominique poisson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:04:22