FastAPI路由在Swagger正常运行,单元测试却返回HTTP 422错误
问题原因及解决方案
你的单元测试写法确实存在问题,核心矛盾在于FastAPI的参数解析规则和你测试时的传参方式不匹配:
为什么会返回422错误?
你的路由函数myroute中,a和b参数未使用任何装饰器(如Body、Form),FastAPI默认会将这类参数识别为查询参数(即通过URL中?a=xxx&b=xxx的形式传递)。但你的单元测试是通过JSON请求体传递参数,FastAPI找不到预期的查询参数,因此返回422错误。
而Swagger测试正常,是因为Swagger会自动识别参数类型,生成查询参数的输入框,你测试时实际是通过URL查询字符串传递的参数,和路由的解析规则完全匹配。
两种解决办法
办法1:修改单元测试,传递查询参数
保持原有路由代码不变,将测试中的json关键字替换为params,让参数通过查询字符串传递:
from fastapi.testclient import TestClient from your_module import api # 替换为你的api所在模块路径 def test_myroute(): client = TestClient(api) response = client.post("/myroute/", params={"a": "dog", "b": "cat"}) assert response.status_code == 200 assert response.text == '"a=dog, b=cat"'
办法2:修改路由,从JSON请求体读取参数
如果业务逻辑需要从JSON请求体接收参数,可以用Pydantic模型定义请求结构:
from fastapi import FastAPI from pydantic import BaseModel api = FastAPI() # 定义请求体数据模型 class MyRequest(BaseModel): a: str b: str @api.post("/myroute/") def myroute(request: MyRequest) -> str: return f"a={request.a}, b={request.b}"
修改后,你原来使用json关键字传参的单元测试就能正常运行了。
内容的提问来源于stack exchange,提问作者W.P. McNeill
相关产品推荐
相关产品推荐

