Python单元测试异常断言失败:AssertionError: Exception not raised
问题原因及修复方案
核心问题分析
测试失败主要是模块级实例化时机与patch作用域不匹配,再加上代码里的几个细节错误:
- 模块实例缓存问题:
sample_module里的abc_class = AbcClass()是在模块加载时执行的,Python会缓存已导入的模块,后续导入不会重新创建实例,导致patch无法作用到已存在的实例上。 - 测试方法参数缺失:
test_func1没有传入self参数,无法调用self.assertRaises(属于语法错误)。 - 拼写错误:
sys.modules['xzy']应为sys.modules['xyz'],拼写错误导致mock未生效。 - 逻辑顺序错误:在
assertRaises内部才执行patch和模块导入,导致patch生效时机晚于实例创建。
修复方案一:重新加载模块确保mock生效
import unittest from unittest.mock import MagicMock, patch import sys import importlib class TestClass(unittest.TestCase): def setUp(self): # 修复拼写错误,提前mock xyz模块 sys.modules['xyz'] = MagicMock() # 清除sample_module缓存,确保每次测试重新加载 if 'src.sample_module' in sys.modules: del sys.modules['src.sample_module'] def test_func1(self): with patch("xyz.AbcClass") as mock_abc: # 给mock实例的方法设置异常 mock_instance = mock_abc.return_value mock_instance.do_something.side_effect = Exception("测试异常") # 重新导入模块,此时模块级实例会使用mock类创建 from src import sample_module # 断言函数执行抛出异常 with self.assertRaises(Exception): sample_module.func1()
修复方案二:直接patch已存在的实例方法(更简洁)
如果不需要控制AbcClass的创建过程,直接针对模块中已存在的abc_class实例进行patch:
import unittest from unittest.mock import patch from src import sample_module class TestClass(unittest.TestCase): def test_func1(self): # 直接patch模块内实例的do_something方法 with patch.object(sample_module.abc_class, 'do_something') as mock_do: mock_do.side_effect = Exception("测试异常") with self.assertRaises(Exception): sample_module.func1()
方案说明
- 方案一适合需要控制
AbcClass实例创建逻辑的场景,确保模块加载时就使用mock类。 - 方案二更轻量化,无需处理模块缓存,直接针对已存在的实例修改方法行为,适合大多数简单测试场景。
内容的提问来源于stack exchange,提问作者Srini
相关产品推荐
相关产品推荐

