python - mock.MagicMock(spec=SomeClass) 和 mock.create_autospec(SomeClass) 有什么区别?
问题描述
我试图了解这两个模拟构造之间的区别以及何时使用其中任何一个都合适。我在解释器中对其进行了测试,例如:
>>> mm = mock.MagicMock(spec=list)
>>> ca = mock.create_autospec(list)
>>> mm
<MagicMock spec='list' id='140372375801232'>
>>> mm()
<MagicMock name='mock()' id='140372384057808'>
>>> mm.append()
<MagicMock name='mock.append()' id='140372375724720'>
>>> mm().append()
<MagicMock name='mock().append()' id='140372375753104'>
>>> ca
<MagicMock spec='list' id='140372384059248'>
>>> ca()
<NonCallableMagicMock name='mock()' spec='list' id='140372384057040'>
>>> ca.append()
<MagicMock name='mock.append()' id='140372375719744'>
>>> ca().append()
<MagicMock name='mock().append()' id='140372375796848'>
>>>
但我不明白为什么“构建”使用创建的模拟create_autospec
给了我 aNonCallableMagicMock
和MagicMock
给了我更多MagicMock
。该文档没有太大帮助。
解决方案
spec
使用参数和使用之间的主要区别create_autospec
是递归性。在第一种情况下,对象本身是指定的,而被调用的对象不是:
>>> mm = mock.MagicMock(spec=list)
>>> mm
<MagicMock spec='list' id='2868486557120'>
>>> mm.foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:\Python\Python38\lib\unittest\mock.py", line 635, in __getattr__
raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'foo'
>>> mm.append
<MagicMock name='mock.append' id='2868486430240'>
>>> mm.append.foo
<MagicMock name='mock.append.foo' id='2868486451408'>
在第二种情况下,调用的对象也被指定(懒惰地):
>>> ca = mock.create_autospec(list)
>>> ca
<MagicMock spec='list' id='2868486254848'>
>>> ca.foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:\Python\Python38\lib\unittest\mock.py", line 635, in __getattr__
raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'foo'
>>> ca.append
<MagicMock name='mock.append' spec='method_descriptor' id='2868486256336'>
>>> ca.append.foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:\Python\Python38\lib\unittest\mock.py", line 635, in __getattr__
raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'foo'
有一个警告,如您的示例代码所示。如果您create_autospec
按照此处所示使用,它的行为就好像该对象是一个类,而不是一个实例,因此您可以调用它(创建一个实例):
>>> ca = mock.create_autospec(list)
>>> ca()
<NonCallableMagicMock name='mock()' spec='list' id='2868485877280'>
如果你想让它表现得像一个实例,你必须使用instance=True
:
>>> ca = mock.create_autospec(list, instance=True)
>>> ca
<NonCallableMagicMock spec='list' id='2868485875024'>
>>> ca()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NonCallableMagicMock' object is not callable
请注意,使用mock.patch
withautospec=True
创建一个模拟,其行为类似于使用创建的模拟,mock.create_autospec
如文档中所述。
另请注意,无论实际调用的返回值如何,调用的返回值始终是 a 。MagicMock
因此,即使函数返回None
,例如list.append
,如果从模拟中调用该方法,也会返回模拟,而不管规范如何。
推荐阅读
- javascript - 使用这些动态输入处理 React 中的状态
- knex.js - 我想知道以后如何将默认()添加和删除到colmun
- dart - 当我尝试实现登录屏幕时抛出异常
- javascript - 如何使用JavaScript检测html中是否同时按下多个键
- python - ImportError:无法从“用户”导入名称“用户”
- typescript - 基于通用输入的通用返回类型
- java - 拖放不适用于java中的chrome webdriver
- c# - OData在.net应用程序中获得零值
- java - 为什么 Java 找不到与类保存在同一文件夹中的 CSV 文件?使用 duke.edu 文件资源
- node.js - 试图将数据从反应(前端)传递到节点服务器(后端)