You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单元测试中如何修改Starlette/FastAPI的Request对象scope字段

问题背景

你现有定义的基础GET请求FastAPI路由代码如下:

@router.get("/reports")
async def get_reports(request: Request) -> Dict:
    return 

初始规划的单元测试代码如下:

def test_method_can_access_request_fields():
    client = TestClient()
    response = client.get("/")

当前已知信息:

  • 路由内接收到的request为starlette.requests.Request类型对象,包含字典类型的scope字段
  • 生产环境使用Mangum将FastAPI部署为AWS Lambda服务时,Request对象会被自动注入aws.event字段
  • 单元测试需要实现通过TestClient修改传入请求的request.scope字典,添加自定义aws.event字段,确认是否可通过传入测试配置参数的方式完成字段注入
实现方案

目前TestClient没有提供直接传入测试配置参数注入scope顶层自定义字段的公开API,推荐通过测试专用中间件的方式实现注入,实现简单且不会侵入生产代码,两种常用实现方式如下:

方法1:单测试用例内注入(适合独立用例)

在单个测试用例内创建独立的测试应用实例,添加临时中间件往请求scope里注入目标字段,测试结束后不会影响生产逻辑:

from fastapi import FastAPI
from starlette.testclient import TestClient
# 导入你项目中定义好的router

def test_method_can_access_request_fields():
    # 初始化测试专用的FastAPI实例
    test_app = FastAPI()
    
    # 注册临时注入中间件
    @test_app.middleware("http")
    async def inject_mock_aws_event(request, call_next):
        # 替换为你业务需要的模拟Lambda event内容
        request.scope["aws.event"] = {
            "version": "2.0",
            "rawPath": "/reports",
            "requestContext": {},
            "headers": {}
        }
        return await call_next(request)
    
    # 挂载业务路由
    test_app.include_router(router)
    
    client = TestClient(test_app)
    # 注意路由路径要和定义的/reports保持一致,原测试代码写的/路径会返回404
    response = client.get("/reports")
    # 后续编写响应断言、request字段校验逻辑即可

方法2:pytest fixture注入(适合多测试用例复用)

如果项目用pytest编写单元测试,可以把注入逻辑封装为公共fixture,所有需要模拟Lambda事件的用例直接调用即可,减少重复代码:

import pytest
from fastapi import FastAPI
from starlette.testclient import TestClient
# 导入你项目中定义好的router

@pytest.fixture
def mock_event_client():
    test_app = FastAPI()
    
    @test_app.middleware("http")
    async def inject_mock_aws_event(request, call_next):
        request.scope["aws.event"] = {
            # 填写通用的模拟Lambda event内容,需要自定义的内容可以在用例内再调整
        }
        return await call_next(request)
    
    test_app.include_router(router)
    yield TestClient(test_app)

# 测试用例直接传入fixture即可使用
def test_method_can_access_request_fields(mock_event_client):
    response = mock_event_client.get("/reports")
    # 编写断言逻辑

注意:不要直接在生产环境使用的FastAPI实例上添加测试中间件,避免测试逻辑污染生产运行流程。


内容的提问来源于stack exchange,提问作者John Kealy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 16:54:07