如何对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
相关产品推荐
相关产品推荐

