如何对APIRouter(非FastAPI实例)抛出的异常进行单元测试
解决方法
根因说明
- TestClient 不支持直接传入
APIRouter实例,必须传入完整的FastAPI应用实例才能正常触发FastAPI内置的异常捕获逻辑 - 原有mock逻辑错误:直接给
DataApiService类设置side_effect会导致实例化阶段就抛出异常,没有进入get_data函数的try-catch块,异常未被捕获转换为HTTP响应,直接向上抛出导致测试失败 - 原有断言中的
start、end变量未定义,会触发变量不存在错误
修正后的测试代码
from fastapi import FastAPI from fastapi.testclient import TestClient from unittest import mock # 导入原代码的路由、自定义异常类 from main import router from your_module_path import EndDataLowerStartDate # 替换为实际异常类所在的模块路径 # 临时创建FastAPI实例,挂载原有路由,无需修改原main.py代码 app = FastAPI() app.include_router(router) client = TestClient(app) def test_get_data_EndDataLowerStartDate(): # 正确mock逻辑:仅让DataApiService实例的validate_dates方法抛出自定义异常 with mock.patch('main.DataApiService') as mock_service_cls: mock_service_instance = mock_service_cls.return_value mock_service_instance.validate_dates.side_effect = EndDataLowerStartDate("2021-01-01", "2021-12-31") response = client.get('/xxxxx', params = {'start': '2021-12-31', 'end': '2021-01-01'}) assert response.status_code == 400 # 可根据实际异常输出调整断言内容 assert response.json() == {'detail': 'End date 2021-01-01 is lower or equal to start date 2021-12-31'}
验证逻辑
- 临时创建的FastAPI实例仅用于测试,完全不会改动原有业务代码
- 修正后的mock会在调用
validate_dates方法时才抛出自定义异常,会被原函数的try-catch捕获并转换为400响应,TestClient可以正常拿到响应结果完成断言
内容的提问来源于stack exchange,提问作者Bemojo
相关产品推荐
相关产品推荐

