Integration testing FastAPI with user authentication.

huangapple go评论61阅读模式
英文:

Integration testing FastAPI with user authentication

问题

我正在尝试编写一些用于测试我的FastAPI端点的集成测试,但不确定测试需要用户登录的端点的最佳解决方案是什么。

我正在按照FastAPI身份验证文档来实现身份验证流程,该流程仅涉及用户名、密码,然后接收一个令牌。

如何测试使用已登录用户的端点?

要测试的示例端点:

@app.get("/lists/{id}", response_model=ListDto)
async def get_list(
    id: int,
    current_user: User = Depends(get_current_active_user),
):
    usecase = GetList(list_id=id, current_user=current_user)
    llist = usecase()
    if not llist:
        raise HTTPException(status_code=404, detail=f"List with id:{id} not found")
    return llist
英文:

I am trying to write some integration tests for my FastAPI endpoints and am not sure what the best solution is to testing the endpoints that require a user to be logged in.

I am following the FastAPI authentication documentation for my auth flow which is just username password and then receiving a token.

How can I test endpoints using a logged in user?

Example endpoint to test:

@app.get("/lists/{id}", response_model=ListDto)
async def get_list(
    id: int,
    current_user: User = Depends(get_current_active_user),
):
    usecase = GetList(list_id=id, current_user=current_user)
    list = usecase()
    if not llist:
        raise HTTPException(status_code=404, detail=f"List with id:{id} not found")
    return list

答案1

得分: 1

为了测试需要用户登录的端点,您需要模拟登录流程以获取有效令牌,然后将其作为标头传递给您后续的请求。以下是您在集成测试中可以这样做的示例:

为您的客户端和测试用户创建一个 fixture

from fastapi.testclient import TestClient
from app.main import app

@pytest.fixture(scope="module")
def client():
    with TestClient(app) as c:
        yield c

@pytest.fixture(scope="module")
def test_user():
    return {"username": "testuser", "password": "testpass"}

编写登录端点的测试用例,用于为您的测试用户获取有效令牌。

def test_login(client, test_user):
    response = client.post("/login", data=test_user)
    assert response.status_code == 200
    token = response.json()["access_token"]
    assert token is not None
    return token

在需要身份验证的后续请求中将令牌作为标头传递。例如,以下是如何测试获取列表端点的方法:

def test_get_list(client, test_user):
    token = test_login(client, test_user)
    response = client.get("/lists/1", headers={"Authorization": f"Bearer {token}"})
    assert response.status_code == 200
    assert response.json()["id"] == 1
英文:

To test endpoints that require a user to be logged in, you will need to simulate a login process to obtain a valid token and then pass it as a header to your subsequent requests. Here is an example of how you can do this in your integration tests:

Create a fixture for your client and a test user

from fastapi.testclient import TestClient
from app.main import app

@pytest.fixture(scope="module")
def client():
    with TestClient(app) as c:
      yield c

@pytest.fixture(scope="module")
def test_user():
    return {"username": "testuser", "password": "testpass"}

Write a test case for the login endpoint that retrieves a valid token for your test user.

def test_login(client, test_user):
  response = client.post("/login", data=test_user)
  assert response.status_code == 200
  token = response.json()["access_token"]
  assert token is not None
  return token

Pass the token as a header in subsequent requests that require authentication. For example, here is how you can test the get_list endpoint:

def test_get_list(client, test_user):
  token = test_login(client, test_user)
  response = client.get("/lists/1", headers={"Authorization": f"Bearer {token}"})
  assert response.status_code == 200
  assert response.json()["id"] == 1

huangapple
  • 本文由 发表于 2023年2月16日 09:06:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/75466872.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定