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

在pytest monkeypatch中Mock函数遇AttributeError,__name__应替换为?

解决Monkeypatch Mock函数时的AttributeError问题

问题根源

你当前代码中用__name__(模块名字符串)作为monkeypatch.setattr的第一个参数,可能因为模块命名空间加载问题,或者直接调用本地函数而非模块属性,导致出现AttributeError或mock不生效。

可行解决方案

方案一:使用当前模块对象(适用于函数和测试在同一文件)

导入sys模块获取当前模块对象,同时调用模块的函数属性而非本地引用:

import sys

def my_function():
    return "original"

def mock_my_function():
    return "mocked"

def test_my_function(monkeypatch):
    # 用模块对象替代模块名字符串
    monkeypatch.setattr(sys.modules[__name__], 'my_function', mock_my_function)
    # 调用模块的my_function属性,确保使用被mock后的版本
    assert sys.modules[__name__].my_function() == "mocked"

方案二:拆分被测试函数到独立模块(更规范的测试结构)

将my_function放到单独的模块文件(如my_module.py):
my_module.py

def my_function():
    return "original"

测试文件中导入该模块,直接patch模块对象:

from my_module import my_function

def mock_my_function():
    return "mocked"

def test_my_function(monkeypatch):
    # 直接传入模块对象或模块名字符串
    monkeypatch.setattr("my_module", 'my_function', mock_my_function)
    # 调用导入的函数,此时已被mock
    assert my_function() == "mocked"

为什么原代码出错

如果my_function是模块级定义的,理论上__name__可行,但报错通常是因为:

  • 函数并非模块级定义(比如写在测试函数内部),模块中无该属性
  • pytest运行环境的模块加载机制,导致通过模块名字符串无法定位到目标函数

用模块对象替代字符串,能精准定位要修改的属性,避免此类问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 16:24:58