You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用pytest测试FastAPI的HTTPException异常场景

核心问题说明

你当前的代码有两个关键问题导致异常场景测不通:

  • /hello接口的try块内只有直接返回固定JSON的逻辑,不存在任何可能抛出requests.exceptions.HTTPError的操作,异常分支永远不会被执行
  • FastAPI内置的异常处理逻辑会自动把接口抛出的HTTPException转换成对应状态码的HTTP响应返回给TestClient,异常不会直接抛到测试代码层,所以你写的pytest.raises(HTTPException)永远捕获不到。response.raise_for_status()是requests库自带的、根据响应状态码抛错的方法,和你接口内部抛出的异常没有关系。
测试实现方案

方案1:增加可控的异常触发参数(适合学习场景)

给接口加一个查询参数,手动控制是否触发异常分支,逻辑清晰最适合学习验证:

# main.py
from fastapi import FastAPI, HTTPException
import requests

app = FastAPI()

@app.get('/hello')
def read_main(trigger_error: bool = False):
    try:
        if trigger_error:
            # 主动抛出requests的HTTPError,模拟真实场景下外部请求失败的情况
            raise requests.exceptions.HTTPError("外部接口调用失败")
        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
from main import app

client = TestClient(app)

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

def test_read_main_error():
    # 传参触发异常分支
    response = client.get("/hello", params={"trigger_error": True})
    assert response.status_code == 400
    assert response.json() == {"detail": "error occured"}

方案2:用Mock模拟异常(适合真实业务场景,不需要改业务代码)

如果你的业务接口本身在try块里有调用外部接口、数据库操作等可能抛错的逻辑,不需要额外加参数,直接用unittest.mock模拟对应逻辑抛出目标异常即可:

# test.py 补充Mock实现
from unittest import mock
import requests
from fastapi.testclient import TestClient
from main import app

client = TestClient(app)

def test_read_main_error_with_mock():
    # 假设try块内原本就有requests.get调用外部接口的逻辑,mock它抛错
    with mock.patch("requests.get", side_effect=requests.exceptions.HTTPError("mock请求失败")):
        response = client.get("/hello")
        assert response.status_code == 400
        assert response.json() == {"detail": "error occured"}

注意:mock的路径需要和你业务代码里实际调用抛错对象的路径保持一致,否则mock不会生效。

内容的提问来源于stack exchange,提问作者SpookyJelly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 01:57:22