调用从"spec"创建的mock的mock方法中不存在的方法时引发错误


from unittest import mock
class A:
def f(self): pass
m = mock.MagicMock(spec_set=A)
m.f.called_once()  # I want this to fail
Out[42]: <MagicMock name='mock.f.called_once()' id='140326790593792'>

我在单元测试中犯了一个错误,在一个模拟方法上调用了called_once而不是assert_called_once。调用会产生一个新的MagicMock实例,因此测试通过了,而没有检查我想要检查的内容——如果调用了该方法。当mock是从spec_set创建的时,如果没有定义方法,有没有办法让mock失败?这就像我希望spec_set一直应用到方法mock本身。

使用create_autospec:

from unittest import mock
class A:
def f(self): pass
m = mock.create_autospec(A)
m.f()
m.f.assert_called_once()  # works OK
m.f.misstyped_called_once() # raises
Traceback (most recent call last):
File "/Users/ant/opt/miniconda3/envs/deeplearning/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3437, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-85-8fe8ab09b722>", line 7, in <module>
m.f.misstyped_called_once() # raises
File "/Users/ant/opt/miniconda3/envs/deeplearning/lib/python3.8/unittest/mock.py", line 637, in __getattr__
raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'misstyped_called_once'

事实证明,文档中有一整节专门讨论这个主题:https://docs.python.org/3/library/unittest.mock.html#autospeccing

自动规范基于mock的现有规范功能。它将mock的api限制为原始对象(规范(的api,但它是递归的(延迟实现(,因此mock的属性只有与规范的属性相同的api。

编辑

看起来有一种学派避免使用assert_called_xxx来支持显式

assert mock_restart.call_count == 1
assert mock_restart.call_args == mock.call(“some argument”)

以及另一所提出方法论解决方案的学校——如果你做TDD,那么在你进行任何实现之前,你的测试必须失败,这可以防止误报。

最新更新