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

如何用aiohttp测试基于Pydantic的FastAPI接口?

解决aiohttp测试FastAPI时Pydantic模型序列化与422验证问题

问题原因与对应解决方案

1. Pydantic模型对象无法JSON序列化

aiohttp的ClientSession.post()方法中json参数只接受Python原生可JSON序列化的类型(比如字典、列表),直接传递Pydantic模型对象会触发TypeError,因为Python默认的JSON序列化器无法识别Pydantic模型结构。

解决方法:
使用Pydantic模型的内置方法将对象转换为字典:

  • Pydantic v2:调用model_dump()方法
  • Pydantic v1:调用dict()方法

2. 传递普通字典返回422错误

422错误的核心原因是请求格式与FastAPI接口期望不匹配:FastAPI的接口参数声明为user: UsersScheme时,默认期望接收application/json格式的请求体,而如果使用data参数传递字典,aiohttp会将数据以application/x-www-form-urlencoded(表单)格式发送,导致Pydantic无法正确解析验证。

解决方法:
确保使用json参数传递字典,而非data参数,aiohttp会自动设置正确的Content-Type: application/json请求头。

修改后的测试用例代码

from src.backend.users.schemas import UsersScheme 
from tests.test_db import test_database_preparation 
import aiohttp

class TestUserAuthentication:
    async def test_user_registration(self, test_database_preparation):
    
        fake_user = {
            "username": "test",
            "non_hashed_password": "test"
        }
        # 方法1:使用Pydantic模型转换后传递
        user: UsersScheme = UsersScheme(**fake_user)
        async with aiohttp.ClientSession() as client_session:
            # Pydantic v2用model_dump(),v1用dict()
            resp = await client_session.post(url="http://localhost:8000/users/register", json=user.model_dump())
            assert resp.status == 200

        # 方法2:直接传递字典(需确保键名与模型完全匹配)
        # async with aiohttp.ClientSession() as client_session:
        #     resp = await client_session.post(url="http://localhost:8000/users/register", json=fake_user)
        #     assert resp.status == 200

额外注意事项

  • 确保测试环境已安装pytest-asyncio插件,否则无法运行异步测试用例,安装命令:pip install pytest-asyncio
  • 确认FastAPI服务在测试前已启动,且测试请求的URL与服务实际地址一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 10:33:17