FastAPI如何测试带有Depends依赖的非端点函数?
问题描述
我有一个依赖user_has_email的/has_email端点,user_has_email本身依赖get_user_info,核心代码如下:
from fastapi import FastAPI, Depends, Request app = FastAPI() def get_user_info(request: Request): user_email = request.username user_info = get_user_info(user_email) # 假设这里是实际获取用户信息的逻辑 return user_info async def user_has_email(user = Depends(get_user_info)): return 'email' in user @app.get("/has_email") def user_email(user_is_registered=Depends(user_has_email)): if user_is_registered: return "Email found!" else: return "No email found!"
我能正常测试get_user_info和/has_email端点,但测试user_has_email时遇到问题。尝试Mockget_user_info后直接调用user_has_email(),预期返回布尔值,实际却得到Depends(get_user_info)对象,测试代码如下:
from fastapi.testclient import TestClient from asyncio import run client = TestClient(app) def mock_get_user_info(): return {"email": "user@test.com"} app.dependency_overrides[get_user_info] = mock_get_user_info def test_user_has_email(): # 预期结果为True,实际得到Depends(get_user_info) result = run(user_has_email())
请问测试user_has_email的正确方法是什么?
解决方法
问题出在直接调用user_has_email()时,FastAPI的依赖注入机制并未生效——Depends(get_user_info)只是FastAPI用于标记依赖的对象,直接调用函数时不会自动解析依赖,因此参数user会保留Depends对象而非实际的用户信息。
有两种简单的测试方式:
方式一:手动传入模拟参数
既然user_has_email的核心逻辑是判断user字典中是否包含email键,你可以直接跳过依赖注入,手动传入模拟的用户对象:
from asyncio import run def test_user_has_email(): # 模拟含email的用户 mock_user_with_email = {"email": "user@test.com"} result = run(user_has_email(user=mock_user_with_email)) assert result is True # 模拟不含email的用户 mock_user_without_email = {"name": "test user"} result = run(user_has_email(user=mock_user_without_email)) assert result is False
这种方式最直接,完全绕开FastAPI的依赖系统,专注测试user_has_email本身的业务逻辑。
方式二:利用FastAPI的依赖解析机制
如果你想完整测试依赖注入链路(确保user_has_email能正确获取get_user_info的返回值),可以用FastAPI的依赖解析器结合依赖覆盖:
from fastapi import Depends from asyncio import run def mock_get_user_info(): return {"email": "user@test.com"} app.dependency_overrides[get_user_info] = mock_get_user_info async def test_user_has_email(): # 通过Depends解析user_has_email的依赖 dependency = Depends(user_has_email) result = await dependency.resolve(app=app) assert result is True
这种方式会让FastAPI自动处理依赖注入,验证整个依赖链路的正确性。
内容的提问来源于stack exchange,提问作者user1367204
相关产品推荐
相关产品推荐

