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

为什么Python unittest的assertRaises方法无法捕获已抛出的异常?

问题根因

  1. 你的tuple_unpacker内部通过try-except捕获了ValueError和TypeError后,仅打印了提示信息,没有将异常重新抛出到函数外部。unittest的assertRaises只能捕获从被测函数向外抛出的未处理异常,自然会判定异常未抛出,第一次测试失败就是这个原因。
  2. 第二种写法属于语法错误:assertRaises的标准入参规则是assertRaises(异常类型, 可调用对象, 入参1, 入参2...),你直接写func((1,'a',1))是先执行了函数,把异常分支返回的None传给了assertRaises,框架尝试调用None对象时抛出了TypeError,属于误打误撞匹配到了你要断言的异常,完全不符合测试逻辑;到第二个断言时框架抛出的TypeError和你要校验的ValueError不匹配,就触发了报错。

解决方案

根据你的业务需求选其中一种即可:

场景1:保留函数内部吞掉异常、只打印提示的逻辑

不需要用assertRaises,改为校验函数的返回值和打印输出即可,示例代码:

import unittest
from io import StringIO
import sys

class TestInner(unittest.TestCase):
    def test_tuple_unpacker(self):
        func = outer()
        # 捕获标准输出校验打印内容
        saved_stdout = sys.stdout
        try:
            sys.stdout = captured_output = StringIO()
            res1 = func((1,'a',1))
            self.assertEqual(captured_output.getvalue().strip(), 'pass only integers in tuple')
            self.assertIsNone(res1)
            
            sys.stdout = captured_output2 = StringIO()
            res2 = func((1,1,1,1))
            self.assertEqual(captured_output2.getvalue().strip(), 'pass tuple with exactly 3 elements')
            self.assertIsNone(res2)
            
            # 正常逻辑校验
            self.assertEqual(func((1,2,3)), 6)
        finally:
            sys.stdout = saved_stdout

场景2:需要函数打印提示后仍向外抛出异常,支持assertRaises校验

先修改原函数的异常分支,打印后加raise重新抛出异常:

def outer():
    def tuple_unpacker( mytuple ):
        try:
            a,b,c = mytuple
            return a+b+c
        except ValueError:
            print('pass tuple with exactly 3 elements')
            raise
        except TypeError:
            print('pass only integers in tuple')
            raise

    return tuple_unpacker

测试代码用标准assertRaises语法即可,更推荐用上下文管理器写法避免参数传递错误:

class TestInner(unittest.TestCase):
    def test_tuple_unpacker(self):
        func = outer()
        # 上下文管理器写法更易读,不易出错
        with self.assertRaises(TypeError):
            func((1,'a',1))
        with self.assertRaises(ValueError):
            func((1,1,1,1))

内容的提问来源于stack exchange,提问作者mn65

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 16:36:01