unittest.mock
in Python 3.x is basically same with mock
.
According to the unittest.mock
documentation:
spec: 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.
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.
spec_set: 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.
Update Difference between spec
and spec_set
.
With spec
, you can set attribute that is not specified, while with spec_set
, it is not allowed to set unspecified attribute.
Example:
>>> 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.c # get -> success (although c is not in the spec)
9
>>> 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'