如何本地测试基于AWS JWT授权器与API网关的FastAPI应用
测试FastAPI + Mangum + AWS JWT授权器的Claims接口
针对你的场景——FastAPI通过Mangum部署在Lambda,依赖API Gateway JWT授权器传递的aws.event claims,这里提供几种可行的测试方案:
方案1:自定义TestClient注入AWS Event数据
FastAPI的TestClient基于Starlette实现,你可以通过子类化重写build_request方法,在请求的scope中注入模拟的aws.event数据,让请求完整经过FastAPI路由处理:
from fastapi.testclient import TestClient from fastapi import FastAPI, Request # 你的FastAPI应用代码 app = FastAPI() @app.get("/claims") async def get_claims(request: Request): return request.scope["aws.event"]["requestContext"]["authorizer"]["claims"] # 自定义支持AWS Event的TestClient class AWSTestClient(TestClient): def build_request(self, method, url, **kwargs): request = super().build_request(method, url, **kwargs) # 注入模拟的AWS JWT授权器返回的claims数据 request.scope["aws.event"] = { "requestContext": { "authorizer": { "claims": { "sub": "test-user-123", "email": "test@example.com", "iss": "https://your-auth-domain/" } } } } return request # 测试用例 def test_get_claims(): client = AWSTestClient(app) response = client.get("/claims") assert response.status_code == 200 assert response.json() == { "sub": "test-user-123", "email": "test@example.com", "iss": "https://your-auth-domain/" }
方案2:用依赖项封装Claims逻辑,测试时替换依赖
把获取claims的逻辑抽成独立依赖项,测试时通过FastAPI的dependency_overrides替换依赖,返回模拟数据,无需修改TestClient:
from fastapi import FastAPI, Request, Depends app = FastAPI() # 封装获取claims的依赖 def extract_claims(request: Request): return request.scope["aws.event"]["requestContext"]["authorizer"]["claims"] @app.get("/claims") async def get_claims_endpoint(claims=Depends(extract_claims)): return claims # 测试用例 def test_claims_with_mock_dependency(): mock_claims = { "sub": "test-user-456", "custom:role": "admin" } client = TestClient(app) # 临时替换依赖项 app.dependency_overrides[extract_claims] = lambda: mock_claims try: response = client.get("/claims") assert response.status_code == 200 assert response.json() == mock_claims finally: # 恢复原依赖,避免影响其他测试 del app.dependency_overrides[extract_claims]
方案3:手动构建Scope调用路由(临时快速测试)
如果只是临时验证接口逻辑,可以手动构建包含aws.event的scope,直接调用路由处理函数:
from fastapi.testclient import TestClient from fastapi import FastAPI, Request from starlette.requests import Request as StarletteRequest app = FastAPI() @app.get("/claims") async def get_claims(request: Request): return request.scope["aws.event"]["requestContext"]["authorizer"]["claims"] def test_claims_direct(): # 手动构建模拟scope mock_scope = { "type": "http", "method": "GET", "path": "/claims", "aws.event": { "requestContext": { "authorizer": { "claims": {"sub": "temp-test-user"} } } } } # 获取对应的路由 claims_route = next(route for route in app.routes if route.path == "/claims") # 创建模拟请求并调用接口 mock_request = StarletteRequest(mock_scope) result = await claims_route.endpoint(mock_request) assert result == {"sub": "temp-test-user"}
方案选择建议
- 方案1适合端到端测试,完整模拟AWS环境下的请求流程,验证路由、中间件等所有逻辑。
- 方案2适合单元测试,聚焦接口本身的业务逻辑,无需关注请求上下文的构建。
- 方案3适合快速调试,不推荐作为正式测试用例。
内容的提问来源于stack exchange,提问作者erik258
相关产品推荐
相关产品推荐

