forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			258 lines
		
	
	
	
		
			7.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			258 lines
		
	
	
	
		
			7.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
 | 
						|
.. 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.
 |