Python单元测试异常抛出失败:LoggableException捕获问题排查
单元测试捕获重抛异常失败问题
我想编写单元测试,验证方法中捕获Exception后重抛LoggableException的逻辑。为触发异常,通过patch模拟logging.info抛出Exception。
当前测试表现
- 被patch的函数抛出Exception(符合预期)
- Exception被捕获并尝试抛出LoggableException(符合预期)
- 函数终止但异常未被测试用例的except块捕获(不符合预期)
- 单元测试失败
预期测试表现
- 触发被patch的Exception
- Exception被捕获并抛出LoggableException
- 测试用例捕获LoggableException,测试通过
相关代码
util.py(不可修改)
class LoggableException(BaseException): def __init__(self, **kwargs): self.message = kwargs['message']
work.py(不可修改)
import logging from util import LoggableException import logging class Server: def __init__(self): logging.getLogger().setLevel(logging.INFO) def cat_work(self): try: logging.info("hi there") except Exception as ex: # addl. stuff raise LoggableException(message='cat was here')
test.py(可修改)
from util import LoggableException from work import Server from unittest.mock import Mock, patch class TestingWork: def __init__(self): self.server = Server() def test_cat_work_thing(self): with patch("logging.info", Mock(side_effect=Exception())): try: self.server.cat_work() assert False except LoggableException: print("Caught the correct exception") except Exception: print("Caught the wrong exception") tests = TestingWork() tests.test_cat_work_thing()
测试输出
[Running] python3 -u "/Users/sudomeacat/Dev/experimental/mock_testing/tests.py" Traceback (most recent call last): File "/Users/sudomeacat/Dev/experimental/mock_testing/work.py", line 12, in cat_work logging.info("hi there") File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/unittest/mock.py", line 1093, in __call__ return self._mock_call(*args, **kwargs) File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/unittest/mock.py", line 1097, in _mock_call return self._execute_mock_call(*args, **kwargs) File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/unittest/mock.py", line 1152, in _execute_mock_call raise effect Exception During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/Users/sudomeacat/Dev/experimental/mock_testing/tests.py", line 18, in <module> tests.test_cat_work_thing() File "/Users/sudomeacat/Dev/experimental/mock_testing/tests.py", line 12, in test_cat_work_thing self.server.cat_work() File "/Users/sudomeacat/Dev/experimental/mock_testing/work.py", line 15, in cat_work raise LoggableException(msg='cat was here', word='not really') File "/Users/sudomeacat/Dev/experimental/mock_testing/util.py", line 3, in __init__ self.msg = kwargs['message'] KeyError: 'message' [Done] exited with code=1 in 0.122 seconds
问题分析与解决
从报错回溯可以明确问题根源:
- 模拟
logging.info抛出Exception的逻辑正常执行 - 进入异常捕获块后,实际运行的
work.py代码中,抛出LoggableException时传入的是msg='cat was here', word='not really',而非你提供代码中的message='cat was here' util.py中LoggableException的构造函数依赖kwargs['message'],缺少该参数直接引发KeyError- 这个
KeyError是未被捕获的新异常,导致测试用例的except LoggableException块无法触发,最终测试失败
解决步骤
- 首先确认测试环境的代码版本:你提供的
work.py代码与实际运行的代码存在参数不一致问题,需同步代码保证抛出LoggableException时传入正确的message参数 - 若
work.py确实不可修改,需检查是否存在其他代码逻辑干扰LoggableException的初始化流程
内容的提问来源于stack exchange,提问作者sudomeacat
相关产品推荐
相关产品推荐

