繁体   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