<p>Python 3.x中的<a href="https://docs.python.org/3/library/unittest.mock.html" rel="noreferrer">^{<cd1>}</a>与<a href="http://pypi.python.org/pypi/mock" rel="noreferrer">^{<cd2>}</a>基本相同。</p>
<p>根据<code>unittest.mock</code>文档:</p>
<blockquote>
<p><strong>spec</strong>: This can be either a list of strings or an existing object (a
class or instance) that acts as the specification for the mock object.
If you pass in an object then a list of strings is formed by calling
dir on the object (excluding unsupported magic attributes and
methods). Accessing any attribute not in this list will raise an
AttributeError.</p>
<p>If spec is an object (rather than a list of strings) then __class__
returns the class of the spec object. This allows mocks to pass
isinstance tests.</p>
<p><strong>spec_set</strong>: A stricter variant of spec. If used, attempting to set or
get an attribute on the mock that isn’t on the object passed as
spec_set will raise an AttributeError.</p>
</blockquote>
<hr/>
<p><strong>更新</strong>在<code>spec</code>和<code>spec_set</code>之间的差异。</p>
<p>使用<code>spec</code>可以设置未指定的属性,而使用<code>spec_set</code>则不允许设置未指定的属性。</p>
<p>示例:</p>
<pre><code>>>> from unittest.mock import Mock
>>> class A:
... def __init__(self, a, b):
... self.a = a
... self.b = b
...
>>> aobj = A(1, 2)
>>> m = Mock(spec=aobj) # spec
>>> m.c # get -> fail
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python3/3.6.0b4_3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/mock.py", line 582, in __getattr__
raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'c'
>>> m.c = 9 # set -> success
>>>
>>> m = Mock(spec_set=aobj) # spec_set
>>> m.a
<Mock name='mock.a' id='4544967400'>
>>> m.b
<Mock name='mock.b' id='4545493928'>
>>> m.c # get -> fail
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python3/3.6.0b4_3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/mock.py", line 582, in __getattr__
raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'c'
>>> m.c = 9 # set -> fail
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python3/3.6.0b4_3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/mock.py", line 688, in __setattr__
raise AttributeError("Mock object has no attribute '%s'" % name)
AttributeError: Mock object has no attribute 'c'
</code></pre>