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