Python 什么';mock.MagicMock(spec=SomeClass)和mock.create\u autospec(SomeClass)之间的区别是什么?

Python 什么';mock.MagicMock(spec=SomeClass)和mock.create\u autospec(SomeClass)之间的区别是什么?,python,mocking,python-unittest,Python,Mocking,Python Unittest,我试图理解这两种模拟结构之间的区别,以及何时使用这两种结构是合适的。我在解释器中进行了测试,例如: mm=mock.MagicMock(spec=list) >>>ca=mock.create\u autospec(列表) >>>嗯 >>>mm() >>>mm.append() >>>mm().append() >>>ca >>>ca() >>>ca.append() >>>ca().append() >>> 但是我不明白为什么使用create\u autospec创建的mock“构造”给了

我试图理解这两种模拟结构之间的区别,以及何时使用这两种结构是合适的。我在解释器中进行了测试,例如:

mm=mock.MagicMock(spec=list) >>>ca=mock.create\u autospec(列表) >>>嗯 >>>mm() >>>mm.append() >>>mm().append() >>>ca >>>ca() >>>ca.append() >>>ca().append() >>>
但是我不明白为什么使用
create\u autospec
创建的mock“构造”给了我一个
NonCallableMagicMock
,而
MagicMock
给了我更多的
MagicMock
。使用
spec
参数和使用
create\u 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'>
如果您想将其表现为实例,则必须使用
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
ca=mock.create\u autospec(list,instance=True) >>>ca >>>ca() 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 TypeError:“NonCallableMagicMock”对象不可调用 请注意,将
mock.patch
autospec=True
一起使用会创建一个行为类似于使用
mock.create\u autospec
创建的模拟,如中所述


还请注意,调用的返回值始终是
MagicMock
,而不管实际调用的返回值如何。因此,即使函数返回
None
,比如
list.append
,如果从mock调用方法,不管规范如何,都会返回mock。

您看过了吗?是的,它不能帮助我理解区别:)主要区别是递归性,但我必须承认,我也不理解你描述的行为。我没想到。。。也许过些时候再看看这个。
>>> ca = mock.create_autospec(list)
>>> ca()
<NonCallableMagicMock name='mock()' spec='list' id='2868485877280'>
>>> 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