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

使用pydantic.BaseModel时unittest.mock打补丁失败,求解决方案

解决Pydantic BaseModel子类实例方法打补丁的AttributeError问题

问题原因

Pydantic的BaseModel通过元类实现模型的字段验证、序列化等核心逻辑,子类的方法属于类属性而非实例属性。当使用patch.object(child_instance, 'method')时,unittest.mock会尝试在实例的__dict__中查找method属性,但该属性仅存在于类层面,因此抛出AttributeError。而普通类的实例允许动态添加属性覆盖类方法,所以不会出现这个问题。

解决方案

方案1:补丁子类的method方法(推荐)

直接针对Child类的method方法打补丁,所有Child实例都会自动使用mock方法:

from unittest.mock import AsyncMock, patch

import pydantic

class Parent(pydantic.BaseModel):
    async def method(self):
        raise NotImplementedError

class Child(Parent):
    async def method(self):
        return False

async def test_patching():
    child_instance = Child()
    # 补丁Child类的method方法,而非实例
    with patch.object(Child, 'method', new_callable=AsyncMock) as mock_method:
        mock_method.return_value = True
        
        assert await child_instance.method() is True

方案2:使用完整路径补丁方法

如果测试代码和模型不在同一模块,可以指定类方法的完整字符串路径:

# 假设Child类在my_module.models模块中
with patch('my_module.models.Child.method', new_callable=AsyncMock) as mock_method:
    child_instance = Child()
    mock_method.return_value = True
    
    assert await child_instance.method() is True

方案3:手动给实例绑定属性(不推荐)

如果必须针对单个实例打补丁,可以先手动将类方法绑定到实例,再执行补丁:

async def test_patching():
    child_instance = Child()
    # 先将类方法绑定到实例,让实例拥有该属性
    child_instance.method = child_instance.method
    with patch.object(child_instance, 'method', new_callable=AsyncMock) as mock_method:
        mock_method.return_value = True
        
        assert await child_instance.method() is True

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 07:12:38