Nie*_*eru 5 python unit-testing mocking python-mock
在 python 中是否有任何等效的严格模拟?一些机制来报告模拟方法的意外调用(在这个例子中是 action.step2()),就像在 GoogleMock 框架中一样。
class Action:
def step1(self, arg):
return False
def step2(self, arg):
return False
def algorithm(action):
action.step1('111')
action.step2('222')
return True
class TestAlgorithm(unittest.TestCase):
def test_algorithm(self):
actionMock = mock.create_autospec(Action)
self.assertTrue(algorithm(actionMock))
actionMock.step1.assert_called_once_with('111')
Run Code Online (Sandbox Code Playgroud)
看起来它不支持开箱即用。然而,至少有两种方法可以实现相同的结果。
根据模拟文档
spec:这可以是字符串列表或充当模拟对象规范的现有对象(类或实例)。如果您传入一个对象,则通过在该对象上调用 dir 来形成一个字符串列表(不包括不受支持的魔法属性和方法)。访问不在此列表中的任何属性将引发 AttributeError。
因此,为了使您的测试示例失败,只需替换
actionMock = mock.create_autospec(Action)
Run Code Online (Sandbox Code Playgroud)
到
actionMock = mock.Mock(spec=['step1'])
Run Code Online (Sandbox Code Playgroud)
与将类或实例作为spec参数传递相比,这种方法有一定的缺点,因为您必须传递所有允许的方法,而不是对它们设置期望,从而有效地将它们注册两次。此外,如果您需要限制方法的子集,则必须传递除这些方法之外的所有方法的列表。这可以通过以下方式实现:
all_members = dir(Action) # according to docs this is what's happening behind the scenes
all_members.remove('step2') # remove all unwanted methods
actionMock = mock.Mock(spec=all_members)
Run Code Online (Sandbox Code Playgroud)
另一种方法是在您不想被调用的方法上明确设置失败:
def test_algorithm(self):
actionMock = mock.create_autospec(Action)
actionMock.step2.side_effect = AttributeError("Called step2") # <<< like this
self.assertTrue(algorithm(actionMock))
actionMock.step1.assert_called_once_with('111')
Run Code Online (Sandbox Code Playgroud)
这也有一些限制:您必须设置错误和期望值。
最后一点,该问题的一个根本解决方案是修补mock以strict向Mock构造函数添加参数并发送拉取请求。要么它会被接受,要么mock维护者会指出如何实现这一点。:)
| 归档时间: |
|
| 查看次数: |
1754 次 |
| 最近记录: |