
fastapi 测试中 `client.get()` 是同步方法,不能直接 `await`;需改用 `async with client.get(...) as response:` 语法获取异步响应对象,避免 `typeerror: object response can't be used in 'await' expression`。
在 FastAPI 的异步测试场景中(如使用 pytest-asyncio),一个常见误区是误将测试客户端的 .get() 方法当作协程函数调用。实际上,TestClient(来自 fastapi.testclient.TestClient)是完全同步的 HTTP 客户端,其所有方法(包括 .get(), .post() 等)均返回普通 Response 对象,不支持 await —— 这正是报错 TypeError: object Response can't be used in 'await' expression 的根本原因。
✅ 正确做法是:改用 httpx.AsyncClient 配合 @pytest.mark.asyncio,它才是为异步测试设计的官方推荐方案。TestClient 仅适用于同步测试;若需真正异步发起请求(例如测试中间件、流式响应或依赖事件循环的行为),必须切换到 AsyncClient。
以下是修正后的完整示例:
import pytest
from httpx import AsyncClient
from your_app.main import app # 替换为你的 FastAPI 实例路径
@pytest.mark.asyncio
async def test_get_report(report_service, headers):
"""Test Report GET Response with true async client"""
report_id = "sample-report-id"
# Mock 服务层(确保其异步方法可被 await)
report_service.query_db.query_fetchone = mock.AsyncMock(
return_value={
"id": "sample-id",
"reportId": "sample-report-id",
"reportName": "sample-report-name",
"report": [],
}
)
# 使用 httpx.AsyncClient(非 TestClient!)
async with AsyncClient(app=app, base_url="http://test") as ac:
response = await ac.get(f"/v2/report/{report_id}", headers=headers)
assert response.status_code == 200
assert response.json()["reportId"] == "sample-report-id"⚠️ 注意事项:
- 确保已安装 httpx:pip install httpx
- AsyncClient(app=app, ...) 会自动挂载 FastAPI 应用到异步测试环境,无需运行真实服务器;
- 若仍使用 TestClient,则不应加 await,也不应尝试 async with(它不支持上下文协议),否则会引发 AttributeError;
- mock.AsyncMock 的返回值需与实际调用链匹配(如 query_fetchone 被 await 调用,因此必须是真正的协程模拟);
- 原始代码中 response.status_code 在 AsyncClient 中对应 response.status_code(保持兼容),但响应体需用 .json() 或 .text 显式解析。
总结:await 错误的本质是客户端类型不匹配。坚持「同步测试用 TestClient + 普通调用」,「异步测试用 AsyncClient + await」,即可彻底规避此类问题。










