最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

pytest - How to mock req: Request in FastAPI unit tests? - Stack Overflow

programmeradmin3浏览0评论

I am writing a unit test for the following FastAPI endpoint:

from fastapi import APIRouter, HTTPException, Depends, Request
from fastapi_cognito import CognitoToken

from app.config.cognito import cognito
from app.user_management import service as user_management_service

api = APIRouter(prefix="/account")

@api.put('/change-password')
def change_password(
    req: Request,
    request: ChangePasswordRequest,
    user: CognitoToken = Depends(cognito.auth_required),
):  
    try:
        token = req.headers["Authorization"].split('Bearer ')[1]

        user_management_service.change_password(
            old_password=request.old_password,
            new_password=request.new_password,
            access_token=token
        )
        
        return ChangePasswordResponse(detail="Password changed")
    except user_management_service.NotAuthorizedException:
        raise HTTPException(401, NotAuthorizedResponse().detail)
    except user_management_service.LimitExceededException:
        raise HTTPException(429, LimitExceededResponse().detail)

I am trying to mock req: Request in my unit test, but I keep running into this error:

self = Headers({'host': 'testserver', 'accept': '*/*', 'accept-encoding': 'gzip, deflate', 'connection': 'keep-alive', 'user-agent': 'testclient', 'content-length': '64', 'content-type': 'application/json'})
key = 'Authorization'

    def __getitem__(self, key: str) -> str:
        get_header_key = key.lower().encode("latin-1")
        for header_key, header_value in self._list:
            if header_key == get_header_key:
                return header_value.decode("latin-1")
>       raise KeyError(key)
E       KeyError: 'Authorization'

/usr/local/lib/python3.12/site-packages/starlette/datastructures.py:539: KeyError

It seems like pytest cannot recognize req when it is not properly initialized as an instance before calling the endpoint?

How should I correctly mock req: Request to include headers only Authorization in unit test?

I am writing a unit test for the following FastAPI endpoint:

from fastapi import APIRouter, HTTPException, Depends, Request
from fastapi_cognito import CognitoToken

from app.config.cognito import cognito
from app.user_management import service as user_management_service

api = APIRouter(prefix="/account")

@api.put('/change-password')
def change_password(
    req: Request,
    request: ChangePasswordRequest,
    user: CognitoToken = Depends(cognito.auth_required),
):  
    try:
        token = req.headers["Authorization"].split('Bearer ')[1]

        user_management_service.change_password(
            old_password=request.old_password,
            new_password=request.new_password,
            access_token=token
        )
        
        return ChangePasswordResponse(detail="Password changed")
    except user_management_service.NotAuthorizedException:
        raise HTTPException(401, NotAuthorizedResponse().detail)
    except user_management_service.LimitExceededException:
        raise HTTPException(429, LimitExceededResponse().detail)

I am trying to mock req: Request in my unit test, but I keep running into this error:

self = Headers({'host': 'testserver', 'accept': '*/*', 'accept-encoding': 'gzip, deflate', 'connection': 'keep-alive', 'user-agent': 'testclient', 'content-length': '64', 'content-type': 'application/json'})
key = 'Authorization'

    def __getitem__(self, key: str) -> str:
        get_header_key = key.lower().encode("latin-1")
        for header_key, header_value in self._list:
            if header_key == get_header_key:
                return header_value.decode("latin-1")
>       raise KeyError(key)
E       KeyError: 'Authorization'

/usr/local/lib/python3.12/site-packages/starlette/datastructures.py:539: KeyError

It seems like pytest cannot recognize req when it is not properly initialized as an instance before calling the endpoint?

How should I correctly mock req: Request to include headers only Authorization in unit test?

Share Improve this question asked Feb 17 at 10:10 MeitaiyangMeitaiyang 112 bronze badges 1
  • 1 Why do you need to mock Request instead of setting up the request properly to match the expected request in your test? (a secondary point: don't use both req and request as variable names in the same functions - you'll get confused very fast and introduce subtle bugs. Use request as the name for Request as that's convention, and instead name your request body according to what it actually represents (for example change_password or something similar). – MatsLindh Commented Feb 18 at 9:18
Add a comment  | 

1 Answer 1

Reset to default 0

Because the error message showed something like Header({....'user-agent': 'test-client'...}), I assume you are using TestClient to test the path operation (PUT - /account/change-password).

Also, since the error message showed KeyError: 'Authorization', I think your request is not properly initialized with the Authorization header.

If you are actually using TestClient for testing, make sure to include the Authorization header in your test code, since your path operation logic (or possibly your Cognito dependency) requires that header.

Below is an example of how to include the Authorization header in your TestClient request:

response = client.put(
    "/account/change-password",
    json={"old_password": "old", "new_password": "new"},
    headers={"Authorization": "Bearer <your_token_here>"}
)
发布评论

评论列表(0)

  1. 暂无评论