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

如何测试FastAPI自定义异常处理器?

问题分析与解决方案

核心错误点

  • pytest.raises() 要求传入异常类而非异常实例,你传了exception(CustomException的实例),这是直接报错的原因。
  • 断言中的e.status_code不存在,你的CustomException类定义的状态码属性是status_code_number,不是status_code。
  • 原测试逻辑没触达真实需求:你要测试的是FastAPI异常处理器,但代码只验证了异常本身的抛出,没验证处理器的响应逻辑。

修正后的测试代码

1. 测试异常本身的正确性

def test_custom_exception_basic():
    inner_exc = InvalidSQLStatement()
    exc = CustomException(inner_exc)
    
    # 验证属性赋值正确
    assert exc.message == inner_exc.message
    assert exc.status_code_number == inner_exc.status_code_number
    
    # 验证异常可被正确抛出捕获
    with pytest.raises(CustomException):
        raise exc

2. 测试FastAPI异常处理器(核心需求)

要验证异常处理器的响应,需通过客户端请求触发异常:

# 先添加一个用于测试的路由(可放在测试文件或临时挂载)
from fastapi import APIRouter

test_router = APIRouter()

@test_router.get("/trigger-custom-exception")
async def trigger_exception():
    raise CustomException(InvalidSQLStatement())

# 测试异常处理器的响应
def test_custom_exception_handler(app_client):
    response = app_client.get("/trigger-custom-exception")
    inner_exc = InvalidSQLStatement()
    
    # 验证响应状态码
    assert response.status_code == inner_exc.status_code_number
    # 验证响应内容格式
    assert response.json() == {inner_exc.status_code_number: inner_exc.message}

错误原因详解

  1. pytest.raises参数错误:pytest.raises()的作用是捕获指定类的异常,传入实例会导致pytest尝试匹配完全相同的对象,不符合异常捕获的逻辑,直接触发报错。
  2. 属性名不匹配:CustomException类中存储状态码的属性是status_code_number,但测试中错误断言e.status_code,会触发AttributeError。
  3. 测试目标偏离:原代码仅验证了异常的抛出,没有测试到异常处理器的核心逻辑——接收异常后返回符合要求的JSON响应。通过客户端请求触发异常,才能真正验证处理器的行为是否符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 16:46:03