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

Python使用unittest.mock.patch.object打补丁后如何恢复被mock方法原始行为

你可以提前保存未被mock的原始方法引用,指定次数的异常抛出完成后直接调用原始方法即可,不需要复制原方法的业务逻辑,修改后的可运行代码如下:

import unittest
from unittest.mock import patch


class Bar(object):

    def some_method_that_may_fail(self):
        return "bar"


class Foo(object):
    bar = None

    def retry_method(self):
        try:
            self.__class__.bar = Bar().some_method_that_may_fail()
        except KeyError:
            self.retry_method()


class TestRetry(unittest.TestCase):

    def setUp(self):
        self.instance = Foo()

    def test_retry(self):
        # 提前保存未被mock的原始方法引用
        original_method = Bar.some_method_that_may_fail
        errors_list = [KeyError("")] * 5

        def raise_errors(*args, **kwargs):
            if errors_list:
                errors_list.pop(0)
                # 前5次调用抛出指定异常
                raise KeyError("")
            # 异常抛完后调用原始方法走原生逻辑
            return original_method(*args, **kwargs)

        with patch.object(Bar, 'some_method_that_may_fail', new=raise_errors) as mocked:
            self.instance.retry_method()
        self.assertEqual(self.instance.bar, 'bar')
        # 可选校验:总共调用6次,前5次失败第6次成功
        self.assertEqual(mocked.call_count, 6)


if __name__ == '__main__':
    unittest.main()

核心实现逻辑

  • 执行patch.object替换方法前,先将原生的Bar.some_method_that_may_fail赋值给临时变量,此时方法还未被mock替换,拿到的是完整的原始业务逻辑
  • 自定义的替换方法中,错误列表不为空时抛出指定异常,列表清空后直接调用提前保存的原始方法,传入调用时的所有参数即可对齐原生调用效果
  • 如果不想自己写闭包逻辑,也可以利用mock对象的side_effect特性实现,写法更简洁:
def test_retry(self):
    original_method = Bar.some_method_that_may_fail
    def call_original(*args, **kwargs):
        return original_method(*args, **kwargs)
    with patch.object(Bar, 'some_method_that_may_fail') as mocked:
        # side_effect按列表顺序依次执行,前5次抛异常,最后一次调用原始方法
        mocked.side_effect = [KeyError("")]*5 + [call_original]
        self.instance.retry_method()
    self.assertEqual(self.instance.bar, 'bar')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 01:45:03