如何测试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}
错误原因详解
- pytest.raises参数错误:
pytest.raises()的作用是捕获指定类的异常,传入实例会导致pytest尝试匹配完全相同的对象,不符合异常捕获的逻辑,直接触发报错。 - 属性名不匹配:CustomException类中存储状态码的属性是
status_code_number,但测试中错误断言e.status_code,会触发AttributeError。 - 测试目标偏离:原代码仅验证了异常的抛出,没有测试到异常处理器的核心逻辑——接收异常后返回符合要求的JSON响应。通过客户端请求触发异常,才能真正验证处理器的行为是否符合预期。
内容的提问来源于stack exchange,提问作者daniel guo
相关产品推荐
相关产品推荐

