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

如何编写pytest测试含datetime字段的FastAPI+Pydantic接口

解决FastAPI异步测试中datetime字段的序列化问题

直接给你几个可行的方案,不用修改Pydantic模型:

方案1:用Pydantic模型自带的json()方法处理

Pydantic模型的json()方法会自动把datetime类型序列化成符合ISO 8601标准的字符串,刚好匹配接口的校验要求。你可以先把模型实例转成JSON字符串,再解析成Python字典传给测试客户端的json参数:

import json
from datetime import datetime
from httpx import AsyncClient
from your_module import MemberCreate, app

async def test_create_member():
    member_data = MemberCreate(
        name="张三",
        birth_date=datetime(1990, 1, 1)
    )
    # 用Pydantic的json()方法处理后转成字典
    payload = json.loads(member_data.json())
    
    async with AsyncClient(app=app, base_url="http://test") as ac:
        response = await ac.post("/members/", json=payload)
    
    assert response.status_code == 200

方案2:手动转换datetime字段为ISO字符串

如果不想用Pydantic的json方法,也可以手动把datetime字段转成ISO格式的字符串,直接构造请求用的字典:

from datetime import datetime
from httpx import AsyncClient
from your_module import MemberCreate, app

async def test_create_member():
    birth_date = datetime(1990, 1, 1)
    payload = {
        "name": "张三",
        "birth_date": birth_date.isoformat()
    }
    
    async with AsyncClient(app=app, base_url="http://test") as ac:
        response = await ac.post("/members/", json=payload)
    
    assert response.status_code == 200

方案3:给测试客户端指定自定义JSON编码器

如果有大量测试用例需要处理datetime,可以给AsyncClient指定自定义的JSON编码器,用Pydantic的默认编码器来处理:

from datetime import datetime
from httpx import AsyncClient
from pydantic.json import pydantic_encoder
from your_module import MemberCreate, app

async def test_create_member():
    member_data = MemberCreate(
        name="张三",
        birth_date=datetime(1990, 1, 1)
    )
    
    # 初始化客户端时指定json_encoder为pydantic_encoder
    async with AsyncClient(
        app=app, 
        base_url="http://test",
        json_encoder=pydantic_encoder
    ) as ac:
        # 直接传模型的dict()结果就行
        response = await ac.post("/members/", json=member_data.dict())
    
    assert response.status_code == 200

为什么之前的方法不行?

  • 直接传member_data.dict():里面的birth_date是datetime对象,httpx的默认JSON编码器无法序列化,所以报错。
  • 用json.dumps()转成字符串后直接传:测试客户端的json参数需要的是Python对象,不是JSON字符串,你传字符串的话会被当成普通文本,接口解析时自然会触发Pydantic的校验错误(因为期望的是JSON对象,不是字符串)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 12:01:07