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

如何对Pydantic自定义验证器进行单元测试?

问题描述

我有一个带自定义验证逻辑的Pydantic类:

class MyClass(BaseModel):
    foo: str

    @validator('foo')
    def perform_custom_validation(cls, val):
       # 此处执行自定义验证逻辑
       raise ValueError('Always fails')

我编写了如下测试代码验证逻辑:

def create_class(a_foo: str):
   MyClass(foo=a_foo)

# 单元测试中
with self.assertRaises(ValidationError):
   create_class('fail')

我认为这段测试应该能捕获到异常,但实际测试失败;不过直接在上下文管理器外调用create_class('fail')会触发异常导致代码运行失败,请问该如何正确测试这个异常抛出逻辑?

解决方法

1. 检查ValidationError的导入正确性

确保你导入的是Pydantic提供的ValidationError,而非其他库的同名类:

from pydantic import ValidationError, BaseModel, validator

2. 匹配实际抛出的异常类型

如果你的验证器中抛出的是ValueError,Pydantic可能不会自动将其包装为ValidationError(取决于Pydantic版本),此时测试需要捕获实际抛出的异常类型:

with self.assertRaises(ValueError):
    create_class('fail')

3. 在验证器中主动抛出Pydantic标准异常

若你期望测试捕获ValidationError,可以在验证逻辑中直接抛出Pydantic的ValidationError或其对应的字段错误类型:

from pydantic import BaseModel, validator, ValidationError

class MyClass(BaseModel):
    foo: str

    @validator('foo')
    def perform_custom_validation(cls, val):
       raise ValidationError('Always fails')

或者使用更规范的字段错误类:

from pydantic import BaseModel, validator, errors

class MyClass(BaseModel):
    foo: str

    @validator('foo')
    def perform_custom_validation(cls, val):
       raise errors.StrError('Always fails')

4. 适配Pydantic v2版本的写法

如果你使用的是Pydantic v2,验证器装饰器已改为@field_validator,且必须加上@classmethod装饰器,此时实例化时会自动抛出ValidationError,你的原有测试代码即可正常工作:

from pydantic import BaseModel, field_validator, ValidationError

class MyClass(BaseModel):
    foo: str

    @field_validator('foo')
    @classmethod
    def perform_custom_validation(cls, val):
       raise ValueError('Always fails')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:13:09