FastAPI官方推荐用TestClient模拟HTTP请求,需传入app实例、手动填充路径参数、用params传查询参数、response.json()解析响应、依赖覆盖用app.dependency_overrides。

用 TestClient 模拟真实 HTTP 请求最直接
FastAPI 官方推荐用 fastapi.testclient.TestClient 包裹应用实例,它底层复用 Starlette 的测试客户端,能走通完整路由、依赖注入、中间件和异常处理器,比手写 httpx.AsyncClient 或 mock 路由函数更可靠。
关键点:必须传入 app 实例(不是模块名或字符串),且不能在 TestClient 初始化时加 base_url —— 它不支持异步上下文,所有请求都走同步阻塞调用,但对测试足够快。
-
TestClient不会启动服务器,不占端口,也不需要uvicorn.run() - 若接口依赖
Depends中的异步函数(比如数据库连接),需提前 patch 或改用同步替代实现,否则会报RuntimeError: async generator ... not awaited - 上传文件要用
files={"file": ("name.txt", b"content", "text/plain")}格式,不能直接传bytes
测试带路径参数和查询参数的接口要写全 URL
TestClient.get() 不自动拼接路径参数(如 /items/{item_id} 中的 {item_id}),必须手动填进 URL 字符串里;查询参数则通过 params 字典传,和 requests 一致。
容易错的地方是混淆 FastAPI 路径模板和实际请求路径 —— 比如定义了 @app.get("/users/{uid}"),测试时得写 client.get("/users/123"),而不是 client.get("/users", params={"uid": "123"}),后者会 404。
立即学习“Python免费学习笔记(深入)”;
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
- 路径参数必须是字符串类型(
client.get("/users/123")),即使路由声明为int,TestClient也会触发类型转换 - 查询参数值如果是
None,会被忽略;空字符串""会作为有效值发送 - 如果接口用了
Body(embed=True),请求体必须套一层 key,比如{"item": {"name": "foo"}}
验证响应状态码和 JSON 数据用 response.status_code 和 response.json()
别用 response.text 手动解析 JSON,response.json() 会自动解码并抛出清晰错误(比如 JSONDecodeError),方便定位响应格式问题。
常见误判:把 status_code == 200 当作“成功”,但 FastAPI 常用 201 Created、204 No Content 等,应严格按接口文档断言。
-
response.json()返回的是 Python 原生对象(dict/list),可直接用assert "key" in resp或assert resp["count"] == 5 - 如果响应是空 body(如
204),调用response.json()会报ValueError: No JSON object could be decoded,此时应先检查response.status_code再决定是否解析 - 二进制响应(如图片)用
response.content,别用.json()
测试依赖项(如数据库)得替换为内存实现或 Mock
真实数据库会让测试变慢、不可靠、难清理。FastAPI 的依赖覆盖机制(app.dependency_overrides)是标准解法:在测试前临时替换依赖函数,测试后清掉。
注意别漏掉 del app.dependency_overrides[xxx],否则会影响后续测试;更稳妥的做法是在 pytest fixture 里用 yield 自动清理。
- 数据库依赖常用
sqlite:///:memory:+create_all()搭配,避免文件 IO - 如果依赖里用了
async def,而你替换成同步函数,TestClient仍能跑通,但逻辑上已偏离运行时行为 —— 这种情况建议用httpx.AsyncClient配合pytest-asyncio - 不要在测试里直接修改全局
app.state,它不会被自动重置,可能污染其他测试

















