Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
michael@0 | 1 | |
michael@0 | 2 | .. currentmodule:: mock |
michael@0 | 3 | |
michael@0 | 4 | |
michael@0 | 5 | .. _magic-methods: |
michael@0 | 6 | |
michael@0 | 7 | Mocking Magic Methods |
michael@0 | 8 | ===================== |
michael@0 | 9 | |
michael@0 | 10 | .. currentmodule:: mock |
michael@0 | 11 | |
michael@0 | 12 | :class:`Mock` supports mocking `magic methods |
michael@0 | 13 | <http://www.ironpythoninaction.com/magic-methods.html>`_. This allows mock |
michael@0 | 14 | objects to replace containers or other objects that implement Python |
michael@0 | 15 | protocols. |
michael@0 | 16 | |
michael@0 | 17 | Because magic methods are looked up differently from normal methods [#]_, this |
michael@0 | 18 | support has been specially implemented. This means that only specific magic |
michael@0 | 19 | methods are supported. The supported list includes *almost* all of them. If |
michael@0 | 20 | there are any missing that you need please let us know! |
michael@0 | 21 | |
michael@0 | 22 | You mock magic methods by setting the method you are interested in to a function |
michael@0 | 23 | or a mock instance. If you are using a function then it *must* take ``self`` as |
michael@0 | 24 | the first argument [#]_. |
michael@0 | 25 | |
michael@0 | 26 | .. doctest:: |
michael@0 | 27 | |
michael@0 | 28 | >>> def __str__(self): |
michael@0 | 29 | ... return 'fooble' |
michael@0 | 30 | ... |
michael@0 | 31 | >>> mock = Mock() |
michael@0 | 32 | >>> mock.__str__ = __str__ |
michael@0 | 33 | >>> str(mock) |
michael@0 | 34 | 'fooble' |
michael@0 | 35 | |
michael@0 | 36 | >>> mock = Mock() |
michael@0 | 37 | >>> mock.__str__ = Mock() |
michael@0 | 38 | >>> mock.__str__.return_value = 'fooble' |
michael@0 | 39 | >>> str(mock) |
michael@0 | 40 | 'fooble' |
michael@0 | 41 | |
michael@0 | 42 | >>> mock = Mock() |
michael@0 | 43 | >>> mock.__iter__ = Mock(return_value=iter([])) |
michael@0 | 44 | >>> list(mock) |
michael@0 | 45 | [] |
michael@0 | 46 | |
michael@0 | 47 | One use case for this is for mocking objects used as context managers in a |
michael@0 | 48 | `with` statement: |
michael@0 | 49 | |
michael@0 | 50 | .. doctest:: |
michael@0 | 51 | |
michael@0 | 52 | >>> mock = Mock() |
michael@0 | 53 | >>> mock.__enter__ = Mock(return_value='foo') |
michael@0 | 54 | >>> mock.__exit__ = Mock(return_value=False) |
michael@0 | 55 | >>> with mock as m: |
michael@0 | 56 | ... assert m == 'foo' |
michael@0 | 57 | ... |
michael@0 | 58 | >>> mock.__enter__.assert_called_with() |
michael@0 | 59 | >>> mock.__exit__.assert_called_with(None, None, None) |
michael@0 | 60 | |
michael@0 | 61 | Calls to magic methods do not appear in :attr:`~Mock.method_calls`, but they |
michael@0 | 62 | are recorded in :attr:`~Mock.mock_calls`. |
michael@0 | 63 | |
michael@0 | 64 | .. note:: |
michael@0 | 65 | |
michael@0 | 66 | If you use the `spec` keyword argument to create a mock then attempting to |
michael@0 | 67 | set a magic method that isn't in the spec will raise an `AttributeError`. |
michael@0 | 68 | |
michael@0 | 69 | The full list of supported magic methods is: |
michael@0 | 70 | |
michael@0 | 71 | * ``__hash__``, ``__sizeof__``, ``__repr__`` and ``__str__`` |
michael@0 | 72 | * ``__dir__``, ``__format__`` and ``__subclasses__`` |
michael@0 | 73 | * ``__floor__``, ``__trunc__`` and ``__ceil__`` |
michael@0 | 74 | * Comparisons: ``__cmp__``, ``__lt__``, ``__gt__``, ``__le__``, ``__ge__``, |
michael@0 | 75 | ``__eq__`` and ``__ne__`` |
michael@0 | 76 | * Container methods: ``__getitem__``, ``__setitem__``, ``__delitem__``, |
michael@0 | 77 | ``__contains__``, ``__len__``, ``__iter__``, ``__getslice__``, |
michael@0 | 78 | ``__setslice__``, ``__reversed__`` and ``__missing__`` |
michael@0 | 79 | * Context manager: ``__enter__`` and ``__exit__`` |
michael@0 | 80 | * Unary numeric methods: ``__neg__``, ``__pos__`` and ``__invert__`` |
michael@0 | 81 | * The numeric methods (including right hand and in-place variants): |
michael@0 | 82 | ``__add__``, ``__sub__``, ``__mul__``, ``__div__``, |
michael@0 | 83 | ``__floordiv__``, ``__mod__``, ``__divmod__``, ``__lshift__``, |
michael@0 | 84 | ``__rshift__``, ``__and__``, ``__xor__``, ``__or__``, and ``__pow__`` |
michael@0 | 85 | * Numeric conversion methods: ``__complex__``, ``__int__``, ``__float__``, |
michael@0 | 86 | ``__index__`` and ``__coerce__`` |
michael@0 | 87 | * Descriptor methods: ``__get__``, ``__set__`` and ``__delete__`` |
michael@0 | 88 | * Pickling: ``__reduce__``, ``__reduce_ex__``, ``__getinitargs__``, |
michael@0 | 89 | ``__getnewargs__``, ``__getstate__`` and ``__setstate__`` |
michael@0 | 90 | |
michael@0 | 91 | |
michael@0 | 92 | The following methods are supported in Python 2 but don't exist in Python 3: |
michael@0 | 93 | |
michael@0 | 94 | * ``__unicode__``, ``__long__``, ``__oct__``, ``__hex__`` and ``__nonzero__`` |
michael@0 | 95 | * ``__truediv__`` and ``__rtruediv__`` |
michael@0 | 96 | |
michael@0 | 97 | The following methods are supported in Python 3 but don't exist in Python 2: |
michael@0 | 98 | |
michael@0 | 99 | * ``__bool__`` and ``__next__`` |
michael@0 | 100 | |
michael@0 | 101 | The following methods exist but are *not* supported as they are either in use by |
michael@0 | 102 | mock, can't be set dynamically, or can cause problems: |
michael@0 | 103 | |
michael@0 | 104 | * ``__getattr__``, ``__setattr__``, ``__init__`` and ``__new__`` |
michael@0 | 105 | * ``__prepare__``, ``__instancecheck__``, ``__subclasscheck__``, ``__del__`` |
michael@0 | 106 | |
michael@0 | 107 | |
michael@0 | 108 | |
michael@0 | 109 | Magic Mock |
michael@0 | 110 | ========== |
michael@0 | 111 | |
michael@0 | 112 | There are two `MagicMock` variants: `MagicMock` and `NonCallableMagicMock`. |
michael@0 | 113 | |
michael@0 | 114 | |
michael@0 | 115 | .. class:: MagicMock(*args, **kw) |
michael@0 | 116 | |
michael@0 | 117 | ``MagicMock`` is a subclass of :class:`Mock` with default implementations |
michael@0 | 118 | of most of the magic methods. You can use ``MagicMock`` without having to |
michael@0 | 119 | configure the magic methods yourself. |
michael@0 | 120 | |
michael@0 | 121 | The constructor parameters have the same meaning as for :class:`Mock`. |
michael@0 | 122 | |
michael@0 | 123 | If you use the `spec` or `spec_set` arguments then *only* magic methods |
michael@0 | 124 | that exist in the spec will be created. |
michael@0 | 125 | |
michael@0 | 126 | |
michael@0 | 127 | .. class:: NonCallableMagicMock(*args, **kw) |
michael@0 | 128 | |
michael@0 | 129 | A non-callable version of `MagicMock`. |
michael@0 | 130 | |
michael@0 | 131 | The constructor parameters have the same meaning as for |
michael@0 | 132 | :class:`MagicMock`, with the exception of `return_value` and |
michael@0 | 133 | `side_effect` which have no meaning on a non-callable mock. |
michael@0 | 134 | |
michael@0 | 135 | The magic methods are setup with `MagicMock` objects, so you can configure them |
michael@0 | 136 | and use them in the usual way: |
michael@0 | 137 | |
michael@0 | 138 | .. doctest:: |
michael@0 | 139 | |
michael@0 | 140 | >>> mock = MagicMock() |
michael@0 | 141 | >>> mock[3] = 'fish' |
michael@0 | 142 | >>> mock.__setitem__.assert_called_with(3, 'fish') |
michael@0 | 143 | >>> mock.__getitem__.return_value = 'result' |
michael@0 | 144 | >>> mock[2] |
michael@0 | 145 | 'result' |
michael@0 | 146 | |
michael@0 | 147 | By default many of the protocol methods are required to return objects of a |
michael@0 | 148 | specific type. These methods are preconfigured with a default return value, so |
michael@0 | 149 | that they can be used without you having to do anything if you aren't interested |
michael@0 | 150 | in the return value. You can still *set* the return value manually if you want |
michael@0 | 151 | to change the default. |
michael@0 | 152 | |
michael@0 | 153 | Methods and their defaults: |
michael@0 | 154 | |
michael@0 | 155 | * ``__lt__``: NotImplemented |
michael@0 | 156 | * ``__gt__``: NotImplemented |
michael@0 | 157 | * ``__le__``: NotImplemented |
michael@0 | 158 | * ``__ge__``: NotImplemented |
michael@0 | 159 | * ``__int__`` : 1 |
michael@0 | 160 | * ``__contains__`` : False |
michael@0 | 161 | * ``__len__`` : 1 |
michael@0 | 162 | * ``__iter__`` : iter([]) |
michael@0 | 163 | * ``__exit__`` : False |
michael@0 | 164 | * ``__complex__`` : 1j |
michael@0 | 165 | * ``__float__`` : 1.0 |
michael@0 | 166 | * ``__bool__`` : True |
michael@0 | 167 | * ``__nonzero__`` : True |
michael@0 | 168 | * ``__oct__`` : '1' |
michael@0 | 169 | * ``__hex__`` : '0x1' |
michael@0 | 170 | * ``__long__`` : long(1) |
michael@0 | 171 | * ``__index__`` : 1 |
michael@0 | 172 | * ``__hash__`` : default hash for the mock |
michael@0 | 173 | * ``__str__`` : default str for the mock |
michael@0 | 174 | * ``__unicode__`` : default unicode for the mock |
michael@0 | 175 | * ``__sizeof__``: default sizeof for the mock |
michael@0 | 176 | |
michael@0 | 177 | For example: |
michael@0 | 178 | |
michael@0 | 179 | .. doctest:: |
michael@0 | 180 | |
michael@0 | 181 | >>> mock = MagicMock() |
michael@0 | 182 | >>> int(mock) |
michael@0 | 183 | 1 |
michael@0 | 184 | >>> len(mock) |
michael@0 | 185 | 0 |
michael@0 | 186 | >>> hex(mock) |
michael@0 | 187 | '0x1' |
michael@0 | 188 | >>> list(mock) |
michael@0 | 189 | [] |
michael@0 | 190 | >>> object() in mock |
michael@0 | 191 | False |
michael@0 | 192 | |
michael@0 | 193 | The two equality method, `__eq__` and `__ne__`, are special (changed in |
michael@0 | 194 | 0.7.2). They do the default equality comparison on identity, using a side |
michael@0 | 195 | effect, unless you change their return value to return something else: |
michael@0 | 196 | |
michael@0 | 197 | .. doctest:: |
michael@0 | 198 | |
michael@0 | 199 | >>> MagicMock() == 3 |
michael@0 | 200 | False |
michael@0 | 201 | >>> MagicMock() != 3 |
michael@0 | 202 | True |
michael@0 | 203 | >>> mock = MagicMock() |
michael@0 | 204 | >>> mock.__eq__.return_value = True |
michael@0 | 205 | >>> mock == 3 |
michael@0 | 206 | True |
michael@0 | 207 | |
michael@0 | 208 | In `0.8` the `__iter__` also gained special handling implemented with a |
michael@0 | 209 | side effect. The return value of `MagicMock.__iter__` can be any iterable |
michael@0 | 210 | object and isn't required to be an iterator: |
michael@0 | 211 | |
michael@0 | 212 | .. doctest:: |
michael@0 | 213 | |
michael@0 | 214 | >>> mock = MagicMock() |
michael@0 | 215 | >>> mock.__iter__.return_value = ['a', 'b', 'c'] |
michael@0 | 216 | >>> list(mock) |
michael@0 | 217 | ['a', 'b', 'c'] |
michael@0 | 218 | >>> list(mock) |
michael@0 | 219 | ['a', 'b', 'c'] |
michael@0 | 220 | |
michael@0 | 221 | If the return value *is* an iterator, then iterating over it once will consume |
michael@0 | 222 | it and subsequent iterations will result in an empty list: |
michael@0 | 223 | |
michael@0 | 224 | .. doctest:: |
michael@0 | 225 | |
michael@0 | 226 | >>> mock.__iter__.return_value = iter(['a', 'b', 'c']) |
michael@0 | 227 | >>> list(mock) |
michael@0 | 228 | ['a', 'b', 'c'] |
michael@0 | 229 | >>> list(mock) |
michael@0 | 230 | [] |
michael@0 | 231 | |
michael@0 | 232 | ``MagicMock`` has all of the supported magic methods configured except for some |
michael@0 | 233 | of the obscure and obsolete ones. You can still set these up if you want. |
michael@0 | 234 | |
michael@0 | 235 | Magic methods that are supported but not setup by default in ``MagicMock`` are: |
michael@0 | 236 | |
michael@0 | 237 | * ``__cmp__`` |
michael@0 | 238 | * ``__getslice__`` and ``__setslice__`` |
michael@0 | 239 | * ``__coerce__`` |
michael@0 | 240 | * ``__subclasses__`` |
michael@0 | 241 | * ``__dir__`` |
michael@0 | 242 | * ``__format__`` |
michael@0 | 243 | * ``__get__``, ``__set__`` and ``__delete__`` |
michael@0 | 244 | * ``__reversed__`` and ``__missing__`` |
michael@0 | 245 | * ``__reduce__``, ``__reduce_ex__``, ``__getinitargs__``, ``__getnewargs__``, |
michael@0 | 246 | ``__getstate__`` and ``__setstate__`` |
michael@0 | 247 | * ``__getformat__`` and ``__setformat__`` |
michael@0 | 248 | |
michael@0 | 249 | |
michael@0 | 250 | |
michael@0 | 251 | ------------ |
michael@0 | 252 | |
michael@0 | 253 | .. [#] Magic methods *should* be looked up on the class rather than the |
michael@0 | 254 | instance. Different versions of Python are inconsistent about applying this |
michael@0 | 255 | rule. The supported protocol methods should work with all supported versions |
michael@0 | 256 | of Python. |
michael@0 | 257 | .. [#] The function is basically hooked up to the class, but each ``Mock`` |
michael@0 | 258 | instance is kept isolated from the others. |