| .. currentmodule:: mock | |
| .. _magic-methods: | |
| Mocking Magic Methods | |
| ===================== | |
| .. currentmodule:: mock | |
| :class:`Mock` supports mocking `magic methods | |
| <http://www.ironpythoninaction.com/magic-methods.html>`_. This allows mock | |
| objects to replace containers or other objects that implement Python | |
| protocols. | |
| Because magic methods are looked up differently from normal methods [#]_, this | |
| support has been specially implemented. This means that only specific magic | |
| methods are supported. The supported list includes *almost* all of them. If | |
| there are any missing that you need please let us know! | |
| You mock magic methods by setting the method you are interested in to a function | |
| or a mock instance. If you are using a function then it *must* take ``self`` as | |
| the first argument [#]_. | |
| .. doctest:: | |
| >>> def __str__(self): | |
| ... return 'fooble' | |
| ... | |
| >>> mock = Mock() | |
| >>> mock.__str__ = __str__ | |
| >>> str(mock) | |
| 'fooble' | |
| >>> mock = Mock() | |
| >>> mock.__str__ = Mock() | |
| >>> mock.__str__.return_value = 'fooble' | |
| >>> str(mock) | |
| 'fooble' | |
| >>> mock = Mock() | |
| >>> mock.__iter__ = Mock(return_value=iter([])) | |
| >>> list(mock) | |
| [] | |
| One use case for this is for mocking objects used as context managers in a | |
| `with` statement: | |
| .. doctest:: | |
| >>> mock = Mock() | |
| >>> mock.__enter__ = Mock(return_value='foo') | |
| >>> mock.__exit__ = Mock(return_value=False) | |
| >>> with mock as m: | |
| ... assert m == 'foo' | |
| ... | |
| >>> mock.__enter__.assert_called_with() | |
| >>> mock.__exit__.assert_called_with(None, None, None) | |
| Calls to magic methods do not appear in :attr:`~Mock.method_calls`, but they | |
| are recorded in :attr:`~Mock.mock_calls`. | |
| .. note:: | |
| If you use the `spec` keyword argument to create a mock then attempting to | |
| set a magic method that isn't in the spec will raise an `AttributeError`. | |
| The full list of supported magic methods is: | |
| * ``__hash__``, ``__sizeof__``, ``__repr__`` and ``__str__`` | |
| * ``__dir__``, ``__format__`` and ``__subclasses__`` | |
| * ``__floor__``, ``__trunc__`` and ``__ceil__`` | |
| * Comparisons: ``__cmp__``, ``__lt__``, ``__gt__``, ``__le__``, ``__ge__``, | |
| ``__eq__`` and ``__ne__`` | |
| * Container methods: ``__getitem__``, ``__setitem__``, ``__delitem__``, | |
| ``__contains__``, ``__len__``, ``__iter__``, ``__getslice__``, | |
| ``__setslice__``, ``__reversed__`` and ``__missing__`` | |
| * Context manager: ``__enter__`` and ``__exit__`` | |
| * Unary numeric methods: ``__neg__``, ``__pos__`` and ``__invert__`` | |
| * The numeric methods (including right hand and in-place variants): | |
| ``__add__``, ``__sub__``, ``__mul__``, ``__div__``, | |
| ``__floordiv__``, ``__mod__``, ``__divmod__``, ``__lshift__``, | |
| ``__rshift__``, ``__and__``, ``__xor__``, ``__or__``, and ``__pow__`` | |
| * Numeric conversion methods: ``__complex__``, ``__int__``, ``__float__``, | |
| ``__index__`` and ``__coerce__`` | |
| * Descriptor methods: ``__get__``, ``__set__`` and ``__delete__`` | |
| * Pickling: ``__reduce__``, ``__reduce_ex__``, ``__getinitargs__``, | |
| ``__getnewargs__``, ``__getstate__`` and ``__setstate__`` | |
| The following methods are supported in Python 2 but don't exist in Python 3: | |
| * ``__unicode__``, ``__long__``, ``__oct__``, ``__hex__`` and ``__nonzero__`` | |
| * ``__truediv__`` and ``__rtruediv__`` | |
| The following methods are supported in Python 3 but don't exist in Python 2: | |
| * ``__bool__`` and ``__next__`` | |
| The following methods exist but are *not* supported as they are either in use by | |
| mock, can't be set dynamically, or can cause problems: | |
| * ``__getattr__``, ``__setattr__``, ``__init__`` and ``__new__`` | |
| * ``__prepare__``, ``__instancecheck__``, ``__subclasscheck__``, ``__del__`` | |
| Magic Mock | |
| ========== | |
| There are two `MagicMock` variants: `MagicMock` and `NonCallableMagicMock`. | |
| .. class:: MagicMock(*args, **kw) | |
| ``MagicMock`` is a subclass of :class:`Mock` with default implementations | |
| of most of the magic methods. You can use ``MagicMock`` without having to | |
| configure the magic methods yourself. | |
| The constructor parameters have the same meaning as for :class:`Mock`. | |
| If you use the `spec` or `spec_set` arguments then *only* magic methods | |
| that exist in the spec will be created. | |
| .. class:: NonCallableMagicMock(*args, **kw) | |
| A non-callable version of `MagicMock`. | |
| The constructor parameters have the same meaning as for | |
| :class:`MagicMock`, with the exception of `return_value` and | |
| `side_effect` which have no meaning on a non-callable mock. | |
| The magic methods are setup with `MagicMock` objects, so you can configure them | |
| and use them in the usual way: | |
| .. doctest:: | |
| >>> mock = MagicMock() | |
| >>> mock[3] = 'fish' | |
| >>> mock.__setitem__.assert_called_with(3, 'fish') | |
| >>> mock.__getitem__.return_value = 'result' | |
| >>> mock[2] | |
| 'result' | |
| By default many of the protocol methods are required to return objects of a | |
| specific type. These methods are preconfigured with a default return value, so | |
| that they can be used without you having to do anything if you aren't interested | |
| in the return value. You can still *set* the return value manually if you want | |
| to change the default. | |
| Methods and their defaults: | |
| * ``__lt__``: NotImplemented | |
| * ``__gt__``: NotImplemented | |
| * ``__le__``: NotImplemented | |
| * ``__ge__``: NotImplemented | |
| * ``__int__`` : 1 | |
| * ``__contains__`` : False | |
| * ``__len__`` : 1 | |
| * ``__iter__`` : iter([]) | |
| * ``__exit__`` : False | |
| * ``__complex__`` : 1j | |
| * ``__float__`` : 1.0 | |
| * ``__bool__`` : True | |
| * ``__nonzero__`` : True | |
| * ``__oct__`` : '1' | |
| * ``__hex__`` : '0x1' | |
| * ``__long__`` : long(1) | |
| * ``__index__`` : 1 | |
| * ``__hash__`` : default hash for the mock | |
| * ``__str__`` : default str for the mock | |
| * ``__unicode__`` : default unicode for the mock | |
| * ``__sizeof__``: default sizeof for the mock | |
| For example: | |
| .. doctest:: | |
| >>> mock = MagicMock() | |
| >>> int(mock) | |
| 1 | |
| >>> len(mock) | |
| 0 | |
| >>> hex(mock) | |
| '0x1' | |
| >>> list(mock) | |
| [] | |
| >>> object() in mock | |
| False | |
| The two equality method, `__eq__` and `__ne__`, are special (changed in | |
| 0.7.2). They do the default equality comparison on identity, using a side | |
| effect, unless you change their return value to return something else: | |
| .. doctest:: | |
| >>> MagicMock() == 3 | |
| False | |
| >>> MagicMock() != 3 | |
| True | |
| >>> mock = MagicMock() | |
| >>> mock.__eq__.return_value = True | |
| >>> mock == 3 | |
| True | |
| In `0.8` the `__iter__` also gained special handling implemented with a | |
| side effect. The return value of `MagicMock.__iter__` can be any iterable | |
| object and isn't required to be an iterator: | |
| .. doctest:: | |
| >>> mock = MagicMock() | |
| >>> mock.__iter__.return_value = ['a', 'b', 'c'] | |
| >>> list(mock) | |
| ['a', 'b', 'c'] | |
| >>> list(mock) | |
| ['a', 'b', 'c'] | |
| If the return value *is* an iterator, then iterating over it once will consume | |
| it and subsequent iterations will result in an empty list: | |
| .. doctest:: | |
| >>> mock.__iter__.return_value = iter(['a', 'b', 'c']) | |
| >>> list(mock) | |
| ['a', 'b', 'c'] | |
| >>> list(mock) | |
| [] | |
| ``MagicMock`` has all of the supported magic methods configured except for some | |
| of the obscure and obsolete ones. You can still set these up if you want. | |
| Magic methods that are supported but not setup by default in ``MagicMock`` are: | |
| * ``__cmp__`` | |
| * ``__getslice__`` and ``__setslice__`` | |
| * ``__coerce__`` | |
| * ``__subclasses__`` | |
| * ``__dir__`` | |
| * ``__format__`` | |
| * ``__get__``, ``__set__`` and ``__delete__`` | |
| * ``__reversed__`` and ``__missing__`` | |
| * ``__reduce__``, ``__reduce_ex__``, ``__getinitargs__``, ``__getnewargs__``, | |
| ``__getstate__`` and ``__setstate__`` | |
| * ``__getformat__`` and ``__setformat__`` | |
| ------------ | |
| .. [#] Magic methods *should* be looked up on the class rather than the | |
| instance. Different versions of Python are inconsistent about applying this | |
| rule. The supported protocol methods should work with all supported versions | |
| of Python. | |
| .. [#] The function is basically hooked up to the class, but each ``Mock`` | |
| instance is kept isolated from the others. |