如何让被@patch修饰的类的实例方法调用时抛出异常?
解决unittest.mock让B.go()抛出异常的问题
问题根源
你第二个测试失败的核心原因是:当用@mock.patch("module_a.B")替换A中引用的B类后,A实例化的self.b是Mock对象的实例,而非原B类的实例。这时候再patchmodule_b.B.go根本不会影响到这个Mock实例的go方法——两者完全是两个独立的对象。
两种可行解决方案
方案1:直接给Mock实例的go方法设置异常
既然已经patch了module_a.B,直接操作这个Mock的返回值(也就是A里的self.b)的go方法即可:
@mock.patch("module_a.B") def test_b_method_go_throws_fix(mock_b: mock.Mock): # 给mock_b的实例(即A里的self.b)的go方法设置异常 mock_b.return_value.go.side_effect = Exception("test") a = A() a.go()
运行后输出:
-- test_b_method_go_throws_fix() -- A constructed OK a.go() threw an exception: Exception('test')
方案2:直接patch A中引用的B.go方法
如果不想mock整个B类,只想让go方法抛异常,可以直接patchmodule_a.B.go(因为A里是from module_b import B,实际在A中使用的B是module_a模块下的引用,必须patch这个路径才生效):
@mock.patch("module_a.B.go") def test_b_method_go_throws_fix2(mock_b_go: mock.Mock): mock_b_go.side_effect = Exception("test") a = A() a.go()
运行后输出:
-- test_b_method_go_throws_fix2() -- B constructed OK A constructed OK a.go() threw an exception: Exception('test')
之前尝试失败的原因
- 尝试1:patch
module_b.B.go无效,因为A里的B是module_a模块中的引用,和原module_b.B的引用链不重合(Python import机制导致)。 - 尝试2:
mock_b.return_value.mock_b_go是错误写法,Mock实例的方法名是go,而非mock_b_go,应该直接用.go访问该方法。
内容的提问来源于stack exchange,提问作者Andrew Cheong
相关产品推荐
相关产品推荐

