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

如何在Python中Mock函数?现有尝试未成功求解决方案

解决Python中Mock自定义函数的问题

看起来你已经搞定了系统函数(比如os.urandom)的Mock,但在Mock自己项目里的foobar函数时遇到了坎儿。核心问题其实是**patch的目标路径不对**——Mock的关键是要替换掉被测试代码实际使用的那个函数引用,而不是原模块里的定义。

先明确你的测试场景,分情况解决

假设你是想在测试用例中替换foobar的行为,我们分两种常见场景处理:

场景1:测试用例直接调用foobar

如果你的测试代码直接调用了从project导入的foobar,那你需要patch的是当前测试模块中foobar的引用(也就是tests.foobar),代码示例如下:

import unittest
from unittest.mock import patch
from project import foobar

def foobar_mock():
    return 'mocked'

class TestProject(unittest.TestCase):
    @patch('tests.foobar', side_effect=foobar_mock)
    def test_foobar_mocked(self, mock_foobar):
        result = foobar()
        self.assertEqual(result, 'mocked')
        mock_foobar.assert_called_once()

场景2:测试其他调用foobar的函数

假设project.py里还有一个依赖foobar的函数,比如:

# project.py
def foobar():
    return 'original'

def use_foobar():
    return foobar()

这时候你要测试use_foobar,就需要patchproject模块内部的foobar引用(也就是project.foobar),代码示例如下:

# tests.py
import unittest
from unittest.mock import patch
from project import use_foobar

def foobar_mock():
    return 'mocked'

class TestProject(unittest.TestCase):
    @patch('project.foobar', side_effect=foobar_mock)
    def test_use_foobar(self, mock_foobar):
        result = use_foobar()
        self.assertEqual(result, 'mocked')
        mock_foobar.assert_called_once()

关键原理帮你理解

unittest.mock.patch的本质是替换某个命名空间中的对象,简单总结:

  • 如果模块A导入了模块B的函数X,且A的函数调用X,那要mock的是A.X,而非B.X
  • 如果是直接测试B模块的X,或者测试代码直接导入X并调用,那要mock的是测试模块中的X(比如tests.X)

回头看你的原有问题

从你提供的代码片段推测,你可能patch了project.foobar,但测试用例里直接调用的是已经导入到tests模块里的foobar引用——这时候替换的是原模块的函数,但测试代码用的还是导入时的旧引用,所以Mock没生效。调整patch的路径就能解决啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:42:34