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

如何用Python单元测试检测是否抛出了嵌套异常?

检测Python异常链中的嵌套异常

问题原因

你的测试失败是因为second_fn实际抛出的是Outer异常,Inner只是这个异常的触发原因(通过raise Outer from e显式关联)。assertRaises默认只会检查顶层抛出的异常类型,不会自动遍历异常链。

解决方案

要验证异常链中的嵌套异常,你需要捕获顶层异常后,通过Python的异常链属性来检查内部异常:

方法1:使用assertRaises上下文管理器

利用上下文管理器获取抛出的Outer异常实例,然后检查其__cause__属性(因为你用了from e显式关联,所以用__cause__;如果是隐式链,用__context__):

import unittest

class Inner(Exception):
    pass

class Outer(Exception):
    pass

def first_fn():
    raise Inner

def second_fn():
    try:
        first_fn()
    except Exception as e:
        raise Outer from e

class MyTestCase(unittest.TestCase):
    def test_case(self):
        with self.assertRaises(Outer) as exception_context:
            second_fn()
        # 验证内部异常类型
        self.assertIsInstance(exception_context.exception.__cause__, Inner)
        # 可选:如果需要验证异常实例或消息,可以进一步断言
        # self.assertEqual(str(exception_context.exception.__cause__), "预期消息")

if __name__ == '__main__':
    unittest.main()

方法2:手动捕获异常

如果你更习惯手动处理异常捕获,也可以这样写:

class MyTestCase(unittest.TestCase):
    def test_case(self):
        try:
            second_fn()
        except Outer as outer_exc:
            # 检查内部异常是否为Inner类型
            self.assertIsInstance(outer_exc.__cause__, Inner)
        else:
            # 如果没有抛出Outer异常,测试失败
            self.fail("未抛出预期的Outer异常")

关键说明

  • __cause__:当使用raise NewExc from OriginalExc时,NewExc.__cause__会指向OriginalExc,用于显式的异常链。
  • __context__:当异常在except块中隐式触发时(没有from),会设置这个属性,代表上下文异常。

这样就能准确验证异常链中的嵌套异常了。

内容的提问来源于stack exchange,提问作者samarendra chandan bindu Dash

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 08:09:24