如何解决mock.MagicMockspec = SomeClass和mock.create_autospecSomeClass有什么区别?
我试图了解这两种模拟结构之间的区别,以及何时适合使用其中一种。我在解释器中对其进行了测试,例如:
>>> 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
创建的模拟会给我一个NonCallableMagicMock
,而MagicMock
给我更多的MagicMock
。 documentation并没有太大帮助。
解决方法
使用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>",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>",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>",in <module>
TypeError: 'NonCallableMagicMock' object is not callable
请注意,将mock.patch
与autospec=True
一起使用会创建一种模拟,其行为类似于使用mock.create_autospec
创建的模拟,如documentation中所述。
还要注意,呼叫的返回值始终为MagicMock
,而不管实际呼叫的返回值如何。因此,即使函数像None
一样返回list.append
,如果从模拟中调用方法,无论规格如何,都会返回模拟。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。