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

如何Mock Python类中通过setattr动态添加的对象方法?

问题原因

你遇到的报错本质上是两个问题导致的:

  1. 拼写错误:你patch的路径是onleet.Onfleet.tasks.get,实际包名是onfleet,拼写错误会直接导致找不到目标对象
  2. 动态属性的特性:tasks不是Onfleet类的固有属性,只有当类实例化执行__init__方法里的_initialize_resources时,才会通过setattr动态绑定到实例上,直接patch类的tasks属性自然找不到目标。
可行解决方案

方案1:完全Mock Onfleet类(最通用,适合绝大多数场景)

直接Mock整个Onfleet类,自定义实例返回的tasks.get行为,不需要依赖原类的初始化逻辑:

from unittest.mock import patch, MagicMock

# 你的被测函数
def get_task(id):
    from onfleet import Onfleet
    api = Onfleet()
    return api.tasks.get(id=id)

def test_get_task():
    mock_onfleet_cls = MagicMock()
    # 配置实例的tasks.get返回值
    mock_onfleet_instance = mock_onfleet_cls.return_value
    mock_onfleet_instance.tasks.get.return_value = {"id": "test_123", "status": 1}

    with patch("onfleet.Onfleet", new=mock_onfleet_cls):
        result = get_task(id="test_123")
        # 验证调用参数正确
        mock_onfleet_instance.tasks.get.assert_called_once_with(id="test_123")
        assert result["id"] == "test_123"

方案2:局部Mock,保留原类其他逻辑

如果你需要保留Onfleet类的其他原有逻辑,只替换tasks.get方法,可以patch_initialize_resources方法,在原生初始化完成后替换目标方法:

from unittest.mock import patch, MagicMock
from onfleet import Onfleet

def test_get_task_partial():
    # 备份原初始化方法
    original_init_res = Onfleet._initialize_resources

    def patched_init_res(self, session):
        # 先执行原生初始化,生成所有端点属性
        original_init_res(self, session)
        # 仅替换tasks.get为mock对象
        self.tasks.get = MagicMock(return_value={})

    with patch.object(Onfleet, "_initialize_resources", new=patched_init_res):
        api = Onfleet(api_key="test_key")
        result = api.tasks.get(id="test_123")
        api.tasks.get.assert_called_once_with(id="test_123")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 18:06:02