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

如何用Pytest测试FastAPI的异常场景?

问题分析

你用pytest.raises(Exception)抓不到异常是因为TestClient是HTTP客户端,FastAPI会自动把路由里的HTTPException转换成标准的HTTP响应返回,不会把Python异常抛给客户端。所以你的测试代码里,client.post("/")不会抛出异常,而是返回一个状态码400的响应对象。


无需修改API路由的测试方案

直接测试响应的状态码和内容即可,这也是测试HTTP API的标准方式,不需要改动原有路由:

def test_function_exception():
    response = client.post("/")
    assert response.status_code == 400
    assert response.json()["detail"] == "failed to do something"

这样既验证了异常场景下的HTTP响应,也能覆盖路由里的try-except逻辑(只要do_something确实抛出了异常)。


若要直接捕获路由内的异常(提升覆盖率验证)

如果想直接验证路由函数内部是否正确抛出了HTTPException(比如为了确保try-except分支确实被触发),可以直接调用路由函数,而不是通过TestClient,同时用pytest.raises捕获HTTPException:

首先在测试中mockdo_something让它抛出异常:

from unittest.mock import patch
from fastapi import HTTPException

def test_function_internal_exception():
    # mock do_something 使其抛出异常
    with patch("your_module.do_something") as mock_do:
        mock_do.side_effect = Exception("test error")
        # 直接调用路由函数
        with pytest.raises(HTTPException) as exc_info:
            my_function()
        # 验证异常的状态码和消息
        assert exc_info.value.status_code == 400
        assert exc_info.value.detail == "failed to do something"

这种方式不需要修改原有路由,只是通过mock和直接调用函数的方式,验证内部的异常处理逻辑,进一步提升代码覆盖率。


总结
  • 无需修改路由:通过TestClient测试HTTP响应的状态码和内容,这是API测试的常规做法。
  • 验证内部逻辑:mock依赖函数后直接调用路由函数,用pytest.raises捕获HTTPException,确保异常处理分支被正确执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:09:21