如何修改 Starlette/FastAPI 中 Request 对象的范围字段以进行单元测试

Joh*_*aly 7 python pytest aws-api-gateway starlette fastapi

假设我有一个带有基本 get 请求的 FastAPI 路由,如下所示:

@router.get("/reports")
async def get_reports(request: Request) -> Dict:
    return 
Run Code Online (Sandbox Code Playgroud)

我想用以下方法测试它:

def test_method_can_access_request_fields():
    client = TestClient()
    response = client.get("/")
Run Code Online (Sandbox Code Playgroud)

现在,如果您检查request路由中的变量,您将看到一个starlette.requests.request对象。该对象有一个 Dict 字段,request.scope.

我们使用 Mangum 将应用程序作为 AWS 上的 Lambda 提供服务,并且我们的实际应用程序能够接收调用aws.event此对象的字段 ( docs )。我正在尝试弄清楚如何为端点编写测试。

我想我想做的是以某种方式修改传入的字典以使用 TestClientrequest.scope包含此自定义字段。aws.event

有没有办法将某些内容传递到测试配置中,从而将自定义字段传播到对象中Request

ish*_*efi 0

首先,为了确保我们不会覆盖当前范围:

def _update_scope(self, scope1, scope2):
    scope1.update(scope2)
    return scope1
Run Code Online (Sandbox Code Playgroud)

然后,创建一个模拟 Starlette 请求的方法,添加您所需的范围:

def mock_request(self, new_scope):
    return lambda scope, send, receive: Request(self._update_scope(scope, new_scope), send, receive)
Run Code Online (Sandbox Code Playgroud)

然后修补starlette.routing.Request


mock.patch("starlette.routing.Request", mock_request())
Run Code Online (Sandbox Code Playgroud)

瞧。