簡體   English   中英

如何使用 pytest 在 fastAPI 中測試 httpError?

[英]How to test httpError in fastAPI with pytest?

我正在嘗試使用 FastAPI 制作一些 api 服務器。 我的項目中有一個名為/hello的端點,它提供:

{味精:“你好世界”}

200 狀態時使用 JSON 格式。

但是,當請求失敗時,它會給出錯誤消息。

很簡單的服務。 但是,我想測試這兩種情況,只是為了我的研究。 所以我也用pytest做了測試代碼。

現在我想知道:如何引發HTTPException並故意對其進行測試?

#main.py (FAST API)

@app.get('/hello')
def read_main():
    try:
        return {"msg":"Hello World"}
    except requests.exceptions.HTTPError as e:
        raise HTTPException(status_code=400,detail='error occured')

#test.py

from fastapi.testclient import TestClient


client = TestClient(app)


# This test works
def test_read_main():
    response = client.get("/hello")
    assert response.json() == {"msg":"Hello World"}
    assert response.status_code == 200

def test_errors():
    # How can I test except in endpoint "/hello" ?
    # The code below never works as I expect
    # with pytest.raises(HTTPException) as e:
    #    raise client.get("/hello").raise_for_status()
    # print(e.value)

這里的問題是你的邏輯是簡單的測試方式。 正如 luk2302 所說; 在當前形式中,您的except塊永遠不會被調用,因此永遠不會被測試。 用更可測試的東西替換你的邏輯,允許我們強制拋出異常。

文件:app.py

from fastapi import FastAPI
from fastapi.exceptions import HTTPException
import requests

app = FastAPI()

#We've put this in a seperate function so we can mock this.
def get_value():
    return {"msg":"Hello World"}

@app.get('/hello')
def read_main():
    try:
        return get_value()
    except requests.exceptions.HTTPError as e:
        raise HTTPException(status_code=400,detail='error occured')

請注意,您的端點的返回值現在實際上由get_value()函數提供。

test.py 文件如下所示:

from fastapi import HTTPException
import app
from fastapi.testclient import TestClient
import requests
from pytest_mock import MockerFixture

client = TestClient(app.app)

def test_read_main():
    response = client.get("/hello")
    assert response.json() == {"msg":"Hello World"}
    assert response.status_code == 200

def get_value_raise():
    raise requests.exceptions.HTTPError()

def test_errors(mocker: MockerFixture):
    mocker.patch("app.get_value", get_value_raise)
    response = client.get("/hello")
    assert response.status_code == 400
    assert response.json() == {"detail": "error occured"}

請注意,我們將app.get_value函數替換為一個肯定會引發您在應用程序邏輯中捕獲的異常類型的函數。 測試客戶端的響應(然而)只是一個 HTTP 響應,但狀態碼為 400 和 json 正文中的詳細信息。 我們為此斷言。

結果:

(.venv) jarro@MBP-van-Jarro test_http_exception % pytest test.py
=================================================== test session starts ===================================================
platform darwin -- Python 3.10.4, pytest-7.1.2, pluggy-1.0.0
rootdir: /Users/jarro/Development/fastapi-github-issues/SO/test_http_exception
plugins: anyio-3.6.1, mock-3.8.2
collected 2 items                                                                                                         

test.py ..                                                                                                          [100%]

==================================================== 2 passed in 0.17s ====================================================

我使用了 pytest,並且通過擴展我使用了 pytest-mocker 來模擬get_value函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM