
.. 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:

* ``__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.
