如何在Python测试中确保仅调用指定方法/属性?
限制Mock对象仅允许指定方法被调用
要实现只有被patch的方法可被调用,其他方法调用直接触发测试失败,可以通过以下几种方式实现:
方法一:使用spec_set严格限制允许的方法
通过spec_set创建Mock实例,仅声明允许调用的方法,任何未声明的方法/属性调用都会直接抛出AttributeError,导致测试失败。
from unittest.mock import patch, Mock class A: def good_fun(self): return "complex operation" def bad_fun(self): print("Oh no!") def test(): # 创建仅允许调用good_fun的Mock实例 mock_a_instance = Mock(spec_set=['good_fun']) mock_a_instance.good_fun.return_value = 3 # 用这个Mock替换A类的实例化逻辑 with patch(f'{__name__}.A', return_value=mock_a_instance): a = A() result = a.good_fun() # 若取消下面的注释,会直接抛出AttributeError,测试失败 # a.bad_fun() assert result == 3 mock_a_instance.good_fun.assert_called_once()
方法二:给禁止调用的方法设置断言错误
如果需要保留原类的结构,但禁止特定方法被调用,可以给这些方法设置side_effect为AssertionError,一旦调用就触发测试失败。
from unittest.mock import patch class A: def good_fun(self): return "complex operation" def bad_fun(self): print("Oh no!") def test(): with patch(f'{__name__}.A') as mock_a_class: # 获取类实例的Mock对象 mock_instance = mock_a_class.return_value # 设置允许调用的方法返回值 mock_instance.good_fun.return_value = 3 # 给禁止调用的方法设置断言错误 mock_instance.bad_fun.side_effect = AssertionError("禁止调用bad_fun方法") a = A() result = a.good_fun() # 若取消下面的注释,会触发AssertionError,测试失败 # a.bad_fun() assert result == 3 mock_instance.good_fun.assert_called_once()
方法三:结合autospec与强制报错
使用autospec=True生成与原类结构一致的Mock,再将不需要的方法设置为调用即报错:
from unittest.mock import patch class A: def good_fun(self): return "complex operation" def bad_fun(self): print("Oh no!") def test(): # autospec=True会生成与A类结构完全一致的Mock with patch(f'{__name__}.A', autospec=True) as mock_a_class: mock_instance = mock_a_class.return_value mock_instance.good_fun.return_value = 3 # 将bad_fun设置为调用就抛出断言错误 mock_instance.bad_fun.side_effect = AssertionError("bad_fun方法不允许被调用") a = A() result = a.good_fun() # 取消注释会触发测试失败 # a.bad_fun() assert result == 3 mock_instance.good_fun.assert_called_once()
其中方法一最为简洁直接,通过spec_set从根源上限制了可调用的方法,适合明确只允许特定方法被调用的场景。
内容的提问来源于stack exchange,提问作者Roberto Morávia
相关产品推荐
相关产品推荐

