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

Unittest.mock.patch无法替换装饰器,测试add函数失败求助

解决Unittest.mock.patch替换装饰器失效的问题

你的patch失败核心原因是模块加载阶段装饰器已执行完毕:当add.py被首次导入时,@decor语法会立刻调用原decor函数包装add,生成被装饰后的版本并存在模块命名空间中。后续patchadd.decor仅替换了模块内的decor函数,但已经生成的add函数不会重新被装饰。

以下是两种可行的修复方案:

方案一:Patch后重新加载模块

利用importlib.reload在patch生效后重新加载add模块,让模块内的@decor使用mock后的装饰器重新包装add函数。

修改后的test_script.py代码:

import functools
from unittest.mock import patch
import importlib
import add  # 先导入模块,供后续reload使用

def mock_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)  # 直接返回原函数结果,不额外加1
    return wrapper

def test_add():
    with patch('add.decor', new=mock_decorator):
        importlib.reload(add)  # 重新加载模块,触发mock装饰器生效
        result = add.add(1, 1)
        assert result == 2

方案二:直接调用原函数的__wrapped__属性

由于你使用了functools.wraps,它会将原函数保存到被装饰函数的__wrapped__属性中,可以直接绕过装饰器调用原函数:

修改后的test_script.py代码:

from add import add

def test_add():
    result = add.__wrapped__(1, 1)  # 调用未被装饰的原始add函数
    assert result == 2

这个方法更简洁,但依赖functools.wraps的实现(如果装饰器未使用该工具,可能不存在__wrapped__属性)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 02:47:21