单元测试中的自定义异常:如何验证自定义DataException的抛出?
如何在单元测试中验证自定义DataException异常
好的,针对你定义的DataException自定义异常,在单元测试里验证它其实挺简单的。核心思路就是捕获抛出的异常实例,然后验证它的属性或者字符串表示是否符合预期。下面我分别用Python自带的unittest框架和常用的pytest框架给你举实际例子:
首先先假设一个会抛出该异常的业务函数(你可以替换成自己项目里的实际函数):
# 示例业务函数:模拟根据条件获取数据的逻辑 def fetch_data(market=None, start_date=None): if market is None and start_date is None: raise DataException('E101') if market is None: raise DataException('E102') if start_date is None: raise DataException('E103') # 正常情况返回数据 return {"data": ["sample"]}
使用Python标准库unittest验证异常
unittest是Python自带的测试框架,不需要额外安装,适合原生项目:
import unittest from errors import DataException from your_module import fetch_data # 替换成你的业务模块实际路径 class TestDataExceptions(unittest.TestCase): def test_e101_exception(self): # 捕获异常并验证 with self.assertRaises(DataException) as context: fetch_data(market=None, start_date=None) # 验证异常的消息文本 self.assertEqual( context.exception.msg, 'There is no data at all for these constraints' ) # 也可以直接验证异常的字符串输出 self.assertEqual( str(context.exception), 'There is no data at all for these constraints' ) def test_e102_exception(self): with self.assertRaises(DataException) as context: fetch_data(start_date='2024-01-01') self.assertEqual( context.exception.msg, 'There is no data for these constraints in this market, try changing market' ) def test_e103_exception(self): with self.assertRaises(DataException) as context: fetch_data(market='US') self.assertEqual( context.exception.msg, 'There is no data for these constraints during these dates, try changing dates' )
使用pytest验证异常
pytest是更简洁灵活的第三方测试框架,需要先通过pip install pytest安装:
import pytest from errors import DataException from your_module import fetch_data def test_e101_exception(): with pytest.raises(DataException) as excinfo: fetch_data(market=None, start_date=None) # 验证异常的msg属性 assert excinfo.value.msg == 'There is no data at all for these constraints' # 验证异常字符串 assert str(excinfo.value) == excinfo.value.msg def test_e102_exception(): with pytest.raises(DataException) as excinfo: fetch_data(start_date='2024-01-01') assert excinfo.value.msg == 'There is no data for these constraints in this market, try changing market' # pytest还支持更简洁的写法,直接匹配异常消息 def test_e103_exception(): pytest.raises( DataException, match='There is no data for these constraints during these dates, try changing dates' )(lambda: fetch_data(market='US'))
额外优化建议
如果想让测试更健壮(避免后续修改错误消息文本导致测试失败),可以给你的DataException添加一个code属性,直接验证错误码:
# 修改errors.py里的异常类 mapper = { 'E101': 'There is no data at all for these constraints', 'E102': 'There is no data for these constraints in this market, try changing market', 'E103': 'There is no data for these constraints during these dates, try changing dates', } class DataException(Exception): def __init__(self, code): super().__init__() self.code = code # 新增code属性 self.msg = mapper[code] def __str__(self): return self.msg
这样测试时可以直接断言错误码,比如:
# unittest示例 self.assertEqual(context.exception.code, 'E102') # pytest示例 assert excinfo.value.code == 'E103'
这种方式比匹配字符串更稳定,适合长期维护的项目。
内容的提问来源于stack exchange,提问作者Ludo
相关产品推荐
相关产品推荐

