【问题标题】:Raise error when calling a non-existent method of a mocked method of a mock created from `spec`调用从`spec`创建的模拟的模拟方法的不存在方法时引发错误
【发布时间】:2021-03-24 11:09:17
【问题描述】:
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 实例,因此测试通过了,而不是检查我打算检查的内容——如果调用了该方法。当从spec_set 创建模拟时,如果未定义方法,是否有办法使模拟失败?就像我希望将 spec_set 一直应用到模拟方法本身。

【问题讨论】:

    标签: python testing mocking python-unittest.mock


    【解决方案1】:

    使用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

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

    编辑

    看起来有一个 school of thought 避免使用 assert_called_xxx 来支持显式

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

    another school 提出了一种方法解决方案——如果您进行 TDD,那么您的测试必须在您实施任何实施之前失败,这样可以防止误报。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多