如何修补 FastAPI 请求

Eyo*_*nyo 1 python unit-testing pytest fastapi

我有一个在我的所有 API 中作为依赖项调用的函数。

from fastapi import HTTPException, Request, status


async def get_user_id_or_401(request: Request) -> str:
    user_id: str = request.headers.get("x-cognito-user-id")

    if not user_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED, detail="Unauthorized"
        )
    return user_id

Run Code Online (Sandbox Code Playgroud)

如何对该功能进行单元测试?我最初的举动是修补request.headers.get,但我不知道该怎么做。

所以,我的问题是,如何修补request.headers.get. 但是,如果我有更好的方法可以对此进行测试,请告诉我。

The*_*ool 5

这就是https://fastapi.tiangolo.com/advanced/testing-dependency/的覆盖内容

像这样的东西:

from fastapi.testclient import TestClient
from main import app


client = TestClient(app)

async def mock_user_id(request):
    return "foo"

app.dependency_overrides[get_user_id_or_401] = mock_user_id

def test_request():
    response = client.get("/")
    assert response.status_code == 200
Run Code Online (Sandbox Code Playgroud)

但我认为最好在测试期间发出请求,这样就不需要向其中添加标头。这也会测试你的功能,否则不会被覆盖。

def test_request():
    response = client.get("/", headers={"x-cognito-user-id": "foo"})
    assert response.status_code == 200
Run Code Online (Sandbox Code Playgroud)

如果您想对您的用户 ID 函数进行单元测试,您可以将其导入到您的测试文件中并实例化一些模拟请求。

请注意,标头键和值应该是字节。所以标头的类型就像list[tuple[byte, byte]].

from starlette import status
from starlette.exceptions import HTTPException
from starlette.requests import Request


def get_user_id_or_401(request: Request) -> str:
    user_id: str = request.headers.get("x-cognito-user-id")

    if not user_id:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED, detail="Unauthorized"
        )
    return user_id


def test_uid():
    r = Request(scope={
        "type": "http",
        "headers": [("x-cognito-user-id".encode(), "foo".encode())],
    })
    assert get_user_id_or_401(r) == "foo"
Run Code Online (Sandbox Code Playgroud)