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

如何对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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:18:03