blob: e650bb1e23e03ee873b3e53ebec7774cfb37d15a [file] [log] [blame]
Michael Foorda9e6fb22012-03-28 14:36:02 +01001:mod:`unittest.mock` --- getting started
2========================================
Michael Foord944e02d2012-03-25 23:12:55 +01003
Michael Foord944e02d2012-03-25 23:12:55 +01004.. moduleauthor:: Michael Foord <michael@python.org>
5.. currentmodule:: unittest.mock
6
7.. versionadded:: 3.3
8
9
Michael Foorda9e6fb22012-03-28 14:36:02 +010010.. _getting-started:
11
Stéphane Wirtel859c0682018-10-12 09:51:05 +020012
13.. testsetup::
14
Xtreakc8dfa732019-09-10 11:37:17 +010015 import asyncio
Stéphane Wirtel859c0682018-10-12 09:51:05 +020016 import unittest
Lisa Roach8b03f942019-09-19 21:04:18 -070017 from unittest.mock import Mock, MagicMock, AsyncMock, patch, call, sentinel
Stéphane Wirtel859c0682018-10-12 09:51:05 +020018
19 class SomeClass:
20 attribute = 'this is a doctest'
21
22 @staticmethod
23 def static_method():
24 pass
25
Michael Foorda9e6fb22012-03-28 14:36:02 +010026Using Mock
27----------
28
29Mock Patching Methods
30~~~~~~~~~~~~~~~~~~~~~
31
32Common uses for :class:`Mock` objects include:
33
34* Patching methods
35* Recording method calls on objects
36
37You might want to replace a method on an object to check that
38it is called with the correct arguments by another part of the system:
39
40 >>> real = SomeClass()
41 >>> real.method = MagicMock(name='method')
42 >>> real.method(3, 4, 5, key='value')
43 <MagicMock name='method()' id='...'>
44
Georg Brandl7ad3df62014-10-31 07:59:37 +010045Once our mock has been used (``real.method`` in this example) it has methods
Michael Foorda9e6fb22012-03-28 14:36:02 +010046and attributes that allow you to make assertions about how it has been used.
47
48.. note::
49
50 In most of these examples the :class:`Mock` and :class:`MagicMock` classes
Georg Brandl7ad3df62014-10-31 07:59:37 +010051 are interchangeable. As the ``MagicMock`` is the more capable class it makes
Michael Foorda9e6fb22012-03-28 14:36:02 +010052 a sensible one to use by default.
53
54Once the mock has been called its :attr:`~Mock.called` attribute is set to
Georg Brandl7ad3df62014-10-31 07:59:37 +010055``True``. More importantly we can use the :meth:`~Mock.assert_called_with` or
Georg Brandl24891672012-04-01 13:48:26 +020056:meth:`~Mock.assert_called_once_with` method to check that it was called with
Michael Foorda9e6fb22012-03-28 14:36:02 +010057the correct arguments.
58
Georg Brandl7ad3df62014-10-31 07:59:37 +010059This example tests that calling ``ProductionClass().method`` results in a call to
60the ``something`` method:
Michael Foorda9e6fb22012-03-28 14:36:02 +010061
Ezio Melottic9cfcf12013-03-11 09:42:40 +020062 >>> class ProductionClass:
Michael Foorda9e6fb22012-03-28 14:36:02 +010063 ... def method(self):
64 ... self.something(1, 2, 3)
65 ... def something(self, a, b, c):
66 ... pass
67 ...
68 >>> real = ProductionClass()
69 >>> real.something = MagicMock()
70 >>> real.method()
71 >>> real.something.assert_called_once_with(1, 2, 3)
72
73
74
75Mock for Method Calls on an Object
76~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
77
78In the last example we patched a method directly on an object to check that it
79was called correctly. Another common use case is to pass an object into a
80method (or some part of the system under test) and then check that it is used
81in the correct way.
82
Georg Brandl7ad3df62014-10-31 07:59:37 +010083The simple ``ProductionClass`` below has a ``closer`` method. If it is called with
84an object then it calls ``close`` on it.
Michael Foorda9e6fb22012-03-28 14:36:02 +010085
Ezio Melottic9cfcf12013-03-11 09:42:40 +020086 >>> class ProductionClass:
Michael Foorda9e6fb22012-03-28 14:36:02 +010087 ... def closer(self, something):
88 ... something.close()
89 ...
90
Georg Brandl7ad3df62014-10-31 07:59:37 +010091So to test it we need to pass in an object with a ``close`` method and check
Michael Foorda9e6fb22012-03-28 14:36:02 +010092that it was called correctly.
93
94 >>> real = ProductionClass()
95 >>> mock = Mock()
96 >>> real.closer(mock)
97 >>> mock.close.assert_called_with()
98
99We don't have to do any work to provide the 'close' method on our mock.
100Accessing close creates it. So, if 'close' hasn't already been called then
101accessing it in the test will create it, but :meth:`~Mock.assert_called_with`
102will raise a failure exception.
103
104
105Mocking Classes
106~~~~~~~~~~~~~~~
107
108A common use case is to mock out classes instantiated by your code under test.
109When you patch a class, then that class is replaced with a mock. Instances
110are created by *calling the class*. This means you access the "mock instance"
111by looking at the return value of the mocked class.
112
Georg Brandl7ad3df62014-10-31 07:59:37 +0100113In the example below we have a function ``some_function`` that instantiates ``Foo``
114and calls a method on it. The call to :func:`patch` replaces the class ``Foo`` with a
115mock. The ``Foo`` instance is the result of calling the mock, so it is configured
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200116by modifying the mock :attr:`~Mock.return_value`. ::
Michael Foorda9e6fb22012-03-28 14:36:02 +0100117
118 >>> def some_function():
119 ... instance = module.Foo()
120 ... return instance.method()
121 ...
122 >>> with patch('module.Foo') as mock:
123 ... instance = mock.return_value
124 ... instance.method.return_value = 'the result'
125 ... result = some_function()
126 ... assert result == 'the result'
127
128
129Naming your mocks
130~~~~~~~~~~~~~~~~~
131
132It can be useful to give your mocks a name. The name is shown in the repr of
133the mock and can be helpful when the mock appears in test failure messages. The
134name is also propagated to attributes or methods of the mock:
135
136 >>> mock = MagicMock(name='foo')
137 >>> mock
138 <MagicMock name='foo' id='...'>
139 >>> mock.method
140 <MagicMock name='foo.method' id='...'>
141
142
143Tracking all Calls
144~~~~~~~~~~~~~~~~~~
145
146Often you want to track more than a single call to a method. The
147:attr:`~Mock.mock_calls` attribute records all calls
148to child attributes of the mock - and also to their children.
149
150 >>> mock = MagicMock()
151 >>> mock.method()
152 <MagicMock name='mock.method()' id='...'>
153 >>> mock.attribute.method(10, x=53)
154 <MagicMock name='mock.attribute.method()' id='...'>
155 >>> mock.mock_calls
156 [call.method(), call.attribute.method(10, x=53)]
157
Georg Brandl7ad3df62014-10-31 07:59:37 +0100158If you make an assertion about ``mock_calls`` and any unexpected methods
Michael Foorda9e6fb22012-03-28 14:36:02 +0100159have been called, then the assertion will fail. This is useful because as well
160as asserting that the calls you expected have been made, you are also checking
161that they were made in the right order and with no additional calls:
162
163You use the :data:`call` object to construct lists for comparing with
Georg Brandl7ad3df62014-10-31 07:59:37 +0100164``mock_calls``:
Michael Foorda9e6fb22012-03-28 14:36:02 +0100165
166 >>> expected = [call.method(), call.attribute.method(10, x=53)]
167 >>> mock.mock_calls == expected
168 True
169
Chris Withers8ca0fa92018-12-03 21:31:37 +0000170However, parameters to calls that return mocks are not recorded, which means it is not
171possible to track nested calls where the parameters used to create ancestors are important:
172
173 >>> m = Mock()
174 >>> m.factory(important=True).deliver()
175 <Mock name='mock.factory().deliver()' id='...'>
176 >>> m.mock_calls[-1] == call.factory(important=False).deliver()
177 True
178
Michael Foorda9e6fb22012-03-28 14:36:02 +0100179
180Setting Return Values and Attributes
181~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
182
183Setting the return values on a mock object is trivially easy:
184
185 >>> mock = Mock()
186 >>> mock.return_value = 3
187 >>> mock()
188 3
189
190Of course you can do the same for methods on the mock:
191
192 >>> mock = Mock()
193 >>> mock.method.return_value = 3
194 >>> mock.method()
195 3
196
197The return value can also be set in the constructor:
198
199 >>> mock = Mock(return_value=3)
200 >>> mock()
201 3
202
203If you need an attribute setting on your mock, just do it:
204
205 >>> mock = Mock()
206 >>> mock.x = 3
207 >>> mock.x
208 3
209
210Sometimes you want to mock up a more complex situation, like for example
Georg Brandl7ad3df62014-10-31 07:59:37 +0100211``mock.connection.cursor().execute("SELECT 1")``. If we wanted this call to
Michael Foorda9e6fb22012-03-28 14:36:02 +0100212return a list, then we have to configure the result of the nested call.
213
214We can use :data:`call` to construct the set of calls in a "chained call" like
215this for easy assertion afterwards:
216
217 >>> mock = Mock()
218 >>> cursor = mock.connection.cursor.return_value
219 >>> cursor.execute.return_value = ['foo']
220 >>> mock.connection.cursor().execute("SELECT 1")
221 ['foo']
222 >>> expected = call.connection.cursor().execute("SELECT 1").call_list()
223 >>> mock.mock_calls
224 [call.connection.cursor(), call.connection.cursor().execute('SELECT 1')]
225 >>> mock.mock_calls == expected
226 True
227
Georg Brandl7ad3df62014-10-31 07:59:37 +0100228It is the call to ``.call_list()`` that turns our call object into a list of
Michael Foorda9e6fb22012-03-28 14:36:02 +0100229calls representing the chained calls.
230
231
232Raising exceptions with mocks
233~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
234
235A useful attribute is :attr:`~Mock.side_effect`. If you set this to an
236exception class or instance then the exception will be raised when the mock
237is called.
238
239 >>> mock = Mock(side_effect=Exception('Boom!'))
240 >>> mock()
241 Traceback (most recent call last):
242 ...
243 Exception: Boom!
244
245
246Side effect functions and iterables
247~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
248
Georg Brandl7ad3df62014-10-31 07:59:37 +0100249``side_effect`` can also be set to a function or an iterable. The use case for
250``side_effect`` as an iterable is where your mock is going to be called several
Michael Foorda9e6fb22012-03-28 14:36:02 +0100251times, and you want each call to return a different value. When you set
Georg Brandl7ad3df62014-10-31 07:59:37 +0100252``side_effect`` to an iterable every call to the mock returns the next value
Michael Foorda9e6fb22012-03-28 14:36:02 +0100253from the iterable:
254
255 >>> mock = MagicMock(side_effect=[4, 5, 6])
256 >>> mock()
257 4
258 >>> mock()
259 5
260 >>> mock()
261 6
262
263
264For more advanced use cases, like dynamically varying the return values
Georg Brandl7ad3df62014-10-31 07:59:37 +0100265depending on what the mock is called with, ``side_effect`` can be a function.
Michael Foorda9e6fb22012-03-28 14:36:02 +0100266The function will be called with the same arguments as the mock. Whatever the
267function returns is what the call returns:
268
269 >>> vals = {(1, 2): 1, (2, 3): 2}
270 >>> def side_effect(*args):
271 ... return vals[args]
272 ...
273 >>> mock = MagicMock(side_effect=side_effect)
274 >>> mock(1, 2)
275 1
276 >>> mock(2, 3)
277 2
278
279
Xtreakc8dfa732019-09-10 11:37:17 +0100280Mocking asynchronous iterators
281~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
282
Lisa Roach8b03f942019-09-19 21:04:18 -0700283Since Python 3.8, ``AsyncMock`` and ``MagicMock`` have support to mock
284:ref:`async-iterators` through ``__aiter__``. The :attr:`~Mock.return_value`
285attribute of ``__aiter__`` can be used to set the return values to be used for
286iteration.
Xtreakc8dfa732019-09-10 11:37:17 +0100287
Lisa Roach8b03f942019-09-19 21:04:18 -0700288 >>> mock = MagicMock() # AsyncMock also works here
Xtreakc8dfa732019-09-10 11:37:17 +0100289 >>> mock.__aiter__.return_value = [1, 2, 3]
290 >>> async def main():
291 ... return [i async for i in mock]
Lisa Roach8b03f942019-09-19 21:04:18 -0700292 ...
Xtreakc8dfa732019-09-10 11:37:17 +0100293 >>> asyncio.run(main())
294 [1, 2, 3]
295
296
297Mocking asynchronous context manager
298~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
299
Lisa Roach8b03f942019-09-19 21:04:18 -0700300Since Python 3.8, ``AsyncMock`` and ``MagicMock`` have support to mock
301:ref:`async-context-managers` through ``__aenter__`` and ``__aexit__``.
302By default, ``__aenter__`` and ``__aexit__`` are ``AsyncMock`` instances that
303return an async function.
Xtreakc8dfa732019-09-10 11:37:17 +0100304
305 >>> class AsyncContextManager:
Xtreakc8dfa732019-09-10 11:37:17 +0100306 ... async def __aenter__(self):
307 ... return self
Lisa Roach8b03f942019-09-19 21:04:18 -0700308 ... async def __aexit__(self, exc_type, exc, tb):
Xtreakc8dfa732019-09-10 11:37:17 +0100309 ... pass
Lisa Roach8b03f942019-09-19 21:04:18 -0700310 ...
311 >>> mock_instance = MagicMock(AsyncContextManager()) # AsyncMock also works here
Xtreakc8dfa732019-09-10 11:37:17 +0100312 >>> async def main():
313 ... async with mock_instance as result:
314 ... pass
Lisa Roach8b03f942019-09-19 21:04:18 -0700315 ...
Xtreakc8dfa732019-09-10 11:37:17 +0100316 >>> asyncio.run(main())
Lisa Roach8b03f942019-09-19 21:04:18 -0700317 >>> mock_instance.__aenter__.assert_awaited_once()
318 >>> mock_instance.__aexit__.assert_awaited_once()
Xtreakc8dfa732019-09-10 11:37:17 +0100319
320
Michael Foorda9e6fb22012-03-28 14:36:02 +0100321Creating a Mock from an Existing Object
322~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
323
324One problem with over use of mocking is that it couples your tests to the
325implementation of your mocks rather than your real code. Suppose you have a
Georg Brandl7ad3df62014-10-31 07:59:37 +0100326class that implements ``some_method``. In a test for another class, you
327provide a mock of this object that *also* provides ``some_method``. If later
328you refactor the first class, so that it no longer has ``some_method`` - then
Michael Foorda9e6fb22012-03-28 14:36:02 +0100329your tests will continue to pass even though your code is now broken!
330
Georg Brandl7ad3df62014-10-31 07:59:37 +0100331:class:`Mock` allows you to provide an object as a specification for the mock,
332using the *spec* keyword argument. Accessing methods / attributes on the
Michael Foorda9e6fb22012-03-28 14:36:02 +0100333mock that don't exist on your specification object will immediately raise an
334attribute error. If you change the implementation of your specification, then
335tests that use that class will start failing immediately without you having to
336instantiate the class in those tests.
337
338 >>> mock = Mock(spec=SomeClass)
339 >>> mock.old_method()
340 Traceback (most recent call last):
341 ...
342 AttributeError: object has no attribute 'old_method'
343
Antoine Pitrou5c64df72013-02-03 00:23:58 +0100344Using a specification also enables a smarter matching of calls made to the
345mock, regardless of whether some parameters were passed as positional or
346named arguments::
347
348 >>> def f(a, b, c): pass
349 ...
350 >>> mock = Mock(spec=f)
351 >>> mock(1, 2, 3)
352 <Mock name='mock()' id='140161580456576'>
353 >>> mock.assert_called_with(a=1, b=2, c=3)
354
355If you want this smarter matching to also work with method calls on the mock,
356you can use :ref:`auto-speccing <auto-speccing>`.
357
Michael Foorda9e6fb22012-03-28 14:36:02 +0100358If you want a stronger form of specification that prevents the setting
359of arbitrary attributes as well as the getting of them then you can use
Georg Brandl7ad3df62014-10-31 07:59:37 +0100360*spec_set* instead of *spec*.
Michael Foorda9e6fb22012-03-28 14:36:02 +0100361
362
363
364Patch Decorators
365----------------
366
367.. note::
368
Georg Brandl7ad3df62014-10-31 07:59:37 +0100369 With :func:`patch` it matters that you patch objects in the namespace where
370 they are looked up. This is normally straightforward, but for a quick guide
Michael Foorda9e6fb22012-03-28 14:36:02 +0100371 read :ref:`where to patch <where-to-patch>`.
372
373
374A common need in tests is to patch a class attribute or a module attribute,
375for example patching a builtin or patching a class in a module to test that it
376is instantiated. Modules and classes are effectively global, so patching on
377them has to be undone after the test or the patch will persist into other
378tests and cause hard to diagnose problems.
379
Georg Brandl7ad3df62014-10-31 07:59:37 +0100380mock provides three convenient decorators for this: :func:`patch`, :func:`patch.object` and
381:func:`patch.dict`. ``patch`` takes a single string, of the form
382``package.module.Class.attribute`` to specify the attribute you are patching. It
Michael Foorda9e6fb22012-03-28 14:36:02 +0100383also optionally takes a value that you want the attribute (or class or
384whatever) to be replaced with. 'patch.object' takes an object and the name of
385the attribute you would like patched, plus optionally the value to patch it
386with.
387
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200388``patch.object``::
Michael Foorda9e6fb22012-03-28 14:36:02 +0100389
390 >>> original = SomeClass.attribute
391 >>> @patch.object(SomeClass, 'attribute', sentinel.attribute)
392 ... def test():
393 ... assert SomeClass.attribute == sentinel.attribute
394 ...
395 >>> test()
396 >>> assert SomeClass.attribute == original
397
398 >>> @patch('package.module.attribute', sentinel.attribute)
399 ... def test():
400 ... from package.module import attribute
401 ... assert attribute is sentinel.attribute
402 ...
403 >>> test()
404
Georg Brandl7ad3df62014-10-31 07:59:37 +0100405If you are patching a module (including :mod:`builtins`) then use :func:`patch`
406instead of :func:`patch.object`:
Michael Foorda9e6fb22012-03-28 14:36:02 +0100407
Ezio Melottib40a2202013-03-30 05:55:52 +0200408 >>> mock = MagicMock(return_value=sentinel.file_handle)
409 >>> with patch('builtins.open', mock):
Michael Foorda9e6fb22012-03-28 14:36:02 +0100410 ... handle = open('filename', 'r')
411 ...
412 >>> mock.assert_called_with('filename', 'r')
413 >>> assert handle == sentinel.file_handle, "incorrect file handle returned"
414
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200415The module name can be 'dotted', in the form ``package.module`` if needed::
Michael Foorda9e6fb22012-03-28 14:36:02 +0100416
417 >>> @patch('package.module.ClassName.attribute', sentinel.attribute)
418 ... def test():
419 ... from package.module import ClassName
420 ... assert ClassName.attribute == sentinel.attribute
421 ...
422 >>> test()
423
424A nice pattern is to actually decorate test methods themselves:
425
Berker Peksagb31daff2016-04-02 04:32:06 +0300426 >>> class MyTest(unittest.TestCase):
Michael Foorda9e6fb22012-03-28 14:36:02 +0100427 ... @patch.object(SomeClass, 'attribute', sentinel.attribute)
428 ... def test_something(self):
429 ... self.assertEqual(SomeClass.attribute, sentinel.attribute)
430 ...
431 >>> original = SomeClass.attribute
432 >>> MyTest('test_something').test_something()
433 >>> assert SomeClass.attribute == original
434
Georg Brandl7ad3df62014-10-31 07:59:37 +0100435If you want to patch with a Mock, you can use :func:`patch` with only one argument
436(or :func:`patch.object` with two arguments). The mock will be created for you and
Michael Foorda9e6fb22012-03-28 14:36:02 +0100437passed into the test function / method:
438
Berker Peksagb31daff2016-04-02 04:32:06 +0300439 >>> class MyTest(unittest.TestCase):
Michael Foorda9e6fb22012-03-28 14:36:02 +0100440 ... @patch.object(SomeClass, 'static_method')
441 ... def test_something(self, mock_method):
442 ... SomeClass.static_method()
443 ... mock_method.assert_called_with()
444 ...
445 >>> MyTest('test_something').test_something()
446
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200447You can stack up multiple patch decorators using this pattern::
Michael Foorda9e6fb22012-03-28 14:36:02 +0100448
Berker Peksagb31daff2016-04-02 04:32:06 +0300449 >>> class MyTest(unittest.TestCase):
Michael Foorda9e6fb22012-03-28 14:36:02 +0100450 ... @patch('package.module.ClassName1')
451 ... @patch('package.module.ClassName2')
452 ... def test_something(self, MockClass2, MockClass1):
Ezio Melottie2123702013-01-10 03:43:33 +0200453 ... self.assertIs(package.module.ClassName1, MockClass1)
454 ... self.assertIs(package.module.ClassName2, MockClass2)
Michael Foorda9e6fb22012-03-28 14:36:02 +0100455 ...
456 >>> MyTest('test_something').test_something()
457
458When you nest patch decorators the mocks are passed in to the decorated
Andrés Delfino271818f2018-09-14 14:13:09 -0300459function in the same order they applied (the normal *Python* order that
Michael Foorda9e6fb22012-03-28 14:36:02 +0100460decorators are applied). This means from the bottom up, so in the example
Georg Brandl7ad3df62014-10-31 07:59:37 +0100461above the mock for ``test_module.ClassName2`` is passed in first.
Michael Foorda9e6fb22012-03-28 14:36:02 +0100462
463There is also :func:`patch.dict` for setting values in a dictionary just
464during a scope and restoring the dictionary to its original state when the test
465ends:
466
467 >>> foo = {'key': 'value'}
468 >>> original = foo.copy()
469 >>> with patch.dict(foo, {'newkey': 'newvalue'}, clear=True):
470 ... assert foo == {'newkey': 'newvalue'}
471 ...
472 >>> assert foo == original
473
Georg Brandl7ad3df62014-10-31 07:59:37 +0100474``patch``, ``patch.object`` and ``patch.dict`` can all be used as context managers.
Michael Foorda9e6fb22012-03-28 14:36:02 +0100475
Georg Brandl7ad3df62014-10-31 07:59:37 +0100476Where you use :func:`patch` to create a mock for you, you can get a reference to the
Michael Foorda9e6fb22012-03-28 14:36:02 +0100477mock using the "as" form of the with statement:
478
Ezio Melottic9cfcf12013-03-11 09:42:40 +0200479 >>> class ProductionClass:
Michael Foorda9e6fb22012-03-28 14:36:02 +0100480 ... def method(self):
481 ... pass
482 ...
483 >>> with patch.object(ProductionClass, 'method') as mock_method:
484 ... mock_method.return_value = None
485 ... real = ProductionClass()
486 ... real.method(1, 2, 3)
487 ...
488 >>> mock_method.assert_called_with(1, 2, 3)
489
490
Georg Brandl7ad3df62014-10-31 07:59:37 +0100491As an alternative ``patch``, ``patch.object`` and ``patch.dict`` can be used as
Michael Foorda9e6fb22012-03-28 14:36:02 +0100492class decorators. When used in this way it is the same as applying the
Larry Hastings3732ed22014-03-15 21:13:56 -0700493decorator individually to every method whose name starts with "test".
Michael Foorda9e6fb22012-03-28 14:36:02 +0100494
495
496.. _further-examples:
497
498Further Examples
Georg Brandl7fc972a2013-02-03 14:00:04 +0100499----------------
Michael Foorda9e6fb22012-03-28 14:36:02 +0100500
501
502Here are some more examples for some slightly more advanced scenarios.
Michael Foord944e02d2012-03-25 23:12:55 +0100503
504
505Mocking chained calls
Georg Brandl7fc972a2013-02-03 14:00:04 +0100506~~~~~~~~~~~~~~~~~~~~~
Michael Foord944e02d2012-03-25 23:12:55 +0100507
508Mocking chained calls is actually straightforward with mock once you
509understand the :attr:`~Mock.return_value` attribute. When a mock is called for
Georg Brandl7ad3df62014-10-31 07:59:37 +0100510the first time, or you fetch its ``return_value`` before it has been called, a
511new :class:`Mock` is created.
Michael Foord944e02d2012-03-25 23:12:55 +0100512
513This means that you can see how the object returned from a call to a mocked
Georg Brandl7ad3df62014-10-31 07:59:37 +0100514object has been used by interrogating the ``return_value`` mock:
Michael Foord944e02d2012-03-25 23:12:55 +0100515
516 >>> mock = Mock()
517 >>> mock().foo(a=2, b=3)
518 <Mock name='mock().foo()' id='...'>
519 >>> mock.return_value.foo.assert_called_with(a=2, b=3)
520
521From here it is a simple step to configure and then make assertions about
522chained calls. Of course another alternative is writing your code in a more
523testable way in the first place...
524
525So, suppose we have some code that looks a little bit like this:
526
Ezio Melottic9cfcf12013-03-11 09:42:40 +0200527 >>> class Something:
Michael Foord944e02d2012-03-25 23:12:55 +0100528 ... def __init__(self):
529 ... self.backend = BackendProvider()
530 ... def method(self):
531 ... response = self.backend.get_endpoint('foobar').create_call('spam', 'eggs').start_call()
532 ... # more code
533
Georg Brandl7ad3df62014-10-31 07:59:37 +0100534Assuming that ``BackendProvider`` is already well tested, how do we test
535``method()``? Specifically, we want to test that the code section ``# more
536code`` uses the response object in the correct way.
Michael Foord944e02d2012-03-25 23:12:55 +0100537
538As this chain of calls is made from an instance attribute we can monkey patch
Georg Brandl7ad3df62014-10-31 07:59:37 +0100539the ``backend`` attribute on a ``Something`` instance. In this particular case
Michael Foord944e02d2012-03-25 23:12:55 +0100540we are only interested in the return value from the final call to
Georg Brandl7ad3df62014-10-31 07:59:37 +0100541``start_call`` so we don't have much configuration to do. Let's assume the
Michael Foord944e02d2012-03-25 23:12:55 +0100542object it returns is 'file-like', so we'll ensure that our response object
Georg Brandl7ad3df62014-10-31 07:59:37 +0100543uses the builtin :func:`open` as its ``spec``.
Michael Foord944e02d2012-03-25 23:12:55 +0100544
545To do this we create a mock instance as our mock backend and create a mock
546response object for it. To set the response as the return value for that final
Georg Brandl7ad3df62014-10-31 07:59:37 +0100547``start_call`` we could do this::
Michael Foord944e02d2012-03-25 23:12:55 +0100548
Georg Brandl7ad3df62014-10-31 07:59:37 +0100549 mock_backend.get_endpoint.return_value.create_call.return_value.start_call.return_value = mock_response
Michael Foord944e02d2012-03-25 23:12:55 +0100550
551We can do that in a slightly nicer way using the :meth:`~Mock.configure_mock`
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200552method to directly set the return value for us::
Michael Foord944e02d2012-03-25 23:12:55 +0100553
554 >>> something = Something()
Terry Jan Reedy30ffe7e2014-01-21 00:01:51 -0500555 >>> mock_response = Mock(spec=open)
Michael Foord944e02d2012-03-25 23:12:55 +0100556 >>> mock_backend = Mock()
557 >>> config = {'get_endpoint.return_value.create_call.return_value.start_call.return_value': mock_response}
558 >>> mock_backend.configure_mock(**config)
559
560With these we monkey patch the "mock backend" in place and can make the real
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200561call::
Michael Foord944e02d2012-03-25 23:12:55 +0100562
563 >>> something.backend = mock_backend
564 >>> something.method()
565
566Using :attr:`~Mock.mock_calls` we can check the chained call with a single
567assert. A chained call is several calls in one line of code, so there will be
Georg Brandl7ad3df62014-10-31 07:59:37 +0100568several entries in ``mock_calls``. We can use :meth:`call.call_list` to create
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200569this list of calls for us::
Michael Foord944e02d2012-03-25 23:12:55 +0100570
571 >>> chained = call.get_endpoint('foobar').create_call('spam', 'eggs').start_call()
572 >>> call_list = chained.call_list()
573 >>> assert mock_backend.mock_calls == call_list
574
575
576Partial mocking
Georg Brandl7fc972a2013-02-03 14:00:04 +0100577~~~~~~~~~~~~~~~
Michael Foord944e02d2012-03-25 23:12:55 +0100578
Georg Brandl7ad3df62014-10-31 07:59:37 +0100579In some tests I wanted to mock out a call to :meth:`datetime.date.today`
Georg Brandl728e4de2014-10-29 09:00:30 +0100580to return a known date, but I didn't want to prevent the code under test from
Georg Brandl7ad3df62014-10-31 07:59:37 +0100581creating new date objects. Unfortunately :class:`datetime.date` is written in C, and
582so I couldn't just monkey-patch out the static :meth:`date.today` method.
Michael Foord944e02d2012-03-25 23:12:55 +0100583
584I found a simple way of doing this that involved effectively wrapping the date
585class with a mock, but passing through calls to the constructor to the real
586class (and returning real instances).
587
588The :func:`patch decorator <patch>` is used here to
Georg Brandl7ad3df62014-10-31 07:59:37 +0100589mock out the ``date`` class in the module under test. The :attr:`side_effect`
Michael Foord944e02d2012-03-25 23:12:55 +0100590attribute on the mock date class is then set to a lambda function that returns
591a real date. When the mock date class is called a real date will be
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200592constructed and returned by ``side_effect``. ::
Michael Foord944e02d2012-03-25 23:12:55 +0100593
594 >>> from datetime import date
595 >>> with patch('mymodule.date') as mock_date:
596 ... mock_date.today.return_value = date(2010, 10, 8)
597 ... mock_date.side_effect = lambda *args, **kw: date(*args, **kw)
598 ...
599 ... assert mymodule.date.today() == date(2010, 10, 8)
600 ... assert mymodule.date(2009, 6, 8) == date(2009, 6, 8)
Michael Foord944e02d2012-03-25 23:12:55 +0100601
Georg Brandl7ad3df62014-10-31 07:59:37 +0100602Note that we don't patch :class:`datetime.date` globally, we patch ``date`` in the
Michael Foord944e02d2012-03-25 23:12:55 +0100603module that *uses* it. See :ref:`where to patch <where-to-patch>`.
604
Georg Brandl7ad3df62014-10-31 07:59:37 +0100605When ``date.today()`` is called a known date is returned, but calls to the
606``date(...)`` constructor still return normal dates. Without this you can find
Michael Foord944e02d2012-03-25 23:12:55 +0100607yourself having to calculate an expected result using exactly the same
608algorithm as the code under test, which is a classic testing anti-pattern.
609
Georg Brandl7ad3df62014-10-31 07:59:37 +0100610Calls to the date constructor are recorded in the ``mock_date`` attributes
611(``call_count`` and friends) which may also be useful for your tests.
Michael Foord944e02d2012-03-25 23:12:55 +0100612
613An alternative way of dealing with mocking dates, or other builtin classes,
614is discussed in `this blog entry
Serhiy Storchaka6dff0202016-05-07 10:49:07 +0300615<https://williambert.online/2011/07/how-to-unit-testing-in-django-with-mocking-and-patching/>`_.
Michael Foord944e02d2012-03-25 23:12:55 +0100616
617
618Mocking a Generator Method
Georg Brandl7fc972a2013-02-03 14:00:04 +0100619~~~~~~~~~~~~~~~~~~~~~~~~~~
Michael Foord944e02d2012-03-25 23:12:55 +0100620
Georg Brandl728e4de2014-10-29 09:00:30 +0100621A Python generator is a function or method that uses the :keyword:`yield` statement
622to return a series of values when iterated over [#]_.
Michael Foord944e02d2012-03-25 23:12:55 +0100623
624A generator method / function is called to return the generator object. It is
625the generator object that is then iterated over. The protocol method for
Georg Brandl728e4de2014-10-29 09:00:30 +0100626iteration is :meth:`~container.__iter__`, so we can
Georg Brandl7ad3df62014-10-31 07:59:37 +0100627mock this using a :class:`MagicMock`.
Michael Foord944e02d2012-03-25 23:12:55 +0100628
629Here's an example class with an "iter" method implemented as a generator:
630
Ezio Melottic9cfcf12013-03-11 09:42:40 +0200631 >>> class Foo:
Michael Foord944e02d2012-03-25 23:12:55 +0100632 ... def iter(self):
633 ... for i in [1, 2, 3]:
634 ... yield i
635 ...
636 >>> foo = Foo()
637 >>> list(foo.iter())
638 [1, 2, 3]
639
640
641How would we mock this class, and in particular its "iter" method?
642
643To configure the values returned from the iteration (implicit in the call to
Georg Brandl7ad3df62014-10-31 07:59:37 +0100644:class:`list`), we need to configure the object returned by the call to ``foo.iter()``.
Michael Foord944e02d2012-03-25 23:12:55 +0100645
646 >>> mock_foo = MagicMock()
647 >>> mock_foo.iter.return_value = iter([1, 2, 3])
648 >>> list(mock_foo.iter())
649 [1, 2, 3]
650
651.. [#] There are also generator expressions and more `advanced uses
652 <http://www.dabeaz.com/coroutines/index.html>`_ of generators, but we aren't
653 concerned about them here. A very good introduction to generators and how
654 powerful they are is: `Generator Tricks for Systems Programmers
655 <http://www.dabeaz.com/generators/>`_.
656
657
658Applying the same patch to every test method
Georg Brandl7fc972a2013-02-03 14:00:04 +0100659~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Michael Foord944e02d2012-03-25 23:12:55 +0100660
661If you want several patches in place for multiple test methods the obvious way
662is to apply the patch decorators to every method. This can feel like unnecessary
Georg Brandl7ad3df62014-10-31 07:59:37 +0100663repetition. For Python 2.6 or more recent you can use :func:`patch` (in all its
Michael Foord944e02d2012-03-25 23:12:55 +0100664various forms) as a class decorator. This applies the patches to all test
665methods on the class. A test method is identified by methods whose names start
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200666with ``test``::
Michael Foord944e02d2012-03-25 23:12:55 +0100667
668 >>> @patch('mymodule.SomeClass')
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200669 ... class MyTest(unittest.TestCase):
Michael Foord944e02d2012-03-25 23:12:55 +0100670 ...
671 ... def test_one(self, MockSomeClass):
Ezio Melottie2123702013-01-10 03:43:33 +0200672 ... self.assertIs(mymodule.SomeClass, MockSomeClass)
Michael Foord944e02d2012-03-25 23:12:55 +0100673 ...
674 ... def test_two(self, MockSomeClass):
Ezio Melottie2123702013-01-10 03:43:33 +0200675 ... self.assertIs(mymodule.SomeClass, MockSomeClass)
Michael Foord944e02d2012-03-25 23:12:55 +0100676 ...
677 ... def not_a_test(self):
678 ... return 'something'
679 ...
680 >>> MyTest('test_one').test_one()
681 >>> MyTest('test_two').test_two()
682 >>> MyTest('test_two').not_a_test()
683 'something'
684
685An alternative way of managing patches is to use the :ref:`start-and-stop`.
Georg Brandl7ad3df62014-10-31 07:59:37 +0100686These allow you to move the patching into your ``setUp`` and ``tearDown`` methods.
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200687::
Michael Foord944e02d2012-03-25 23:12:55 +0100688
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200689 >>> class MyTest(unittest.TestCase):
Michael Foord944e02d2012-03-25 23:12:55 +0100690 ... def setUp(self):
691 ... self.patcher = patch('mymodule.foo')
692 ... self.mock_foo = self.patcher.start()
693 ...
694 ... def test_foo(self):
Ezio Melottie2123702013-01-10 03:43:33 +0200695 ... self.assertIs(mymodule.foo, self.mock_foo)
Michael Foord944e02d2012-03-25 23:12:55 +0100696 ...
697 ... def tearDown(self):
698 ... self.patcher.stop()
699 ...
700 >>> MyTest('test_foo').run()
701
702If you use this technique you must ensure that the patching is "undone" by
Georg Brandl7ad3df62014-10-31 07:59:37 +0100703calling ``stop``. This can be fiddlier than you might think, because if an
Michael Foord944e02d2012-03-25 23:12:55 +0100704exception is raised in the setUp then tearDown is not called.
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200705:meth:`unittest.TestCase.addCleanup` makes this easier::
Michael Foord944e02d2012-03-25 23:12:55 +0100706
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200707 >>> class MyTest(unittest.TestCase):
Michael Foord944e02d2012-03-25 23:12:55 +0100708 ... def setUp(self):
709 ... patcher = patch('mymodule.foo')
710 ... self.addCleanup(patcher.stop)
711 ... self.mock_foo = patcher.start()
712 ...
713 ... def test_foo(self):
Ezio Melottie2123702013-01-10 03:43:33 +0200714 ... self.assertIs(mymodule.foo, self.mock_foo)
Michael Foord944e02d2012-03-25 23:12:55 +0100715 ...
716 >>> MyTest('test_foo').run()
717
718
719Mocking Unbound Methods
Georg Brandl7fc972a2013-02-03 14:00:04 +0100720~~~~~~~~~~~~~~~~~~~~~~~
Michael Foord944e02d2012-03-25 23:12:55 +0100721
722Whilst writing tests today I needed to patch an *unbound method* (patching the
723method on the class rather than on the instance). I needed self to be passed
724in as the first argument because I want to make asserts about which objects
725were calling this particular method. The issue is that you can't patch with a
726mock for this, because if you replace an unbound method with a mock it doesn't
727become a bound method when fetched from the instance, and so it doesn't get
728self passed in. The workaround is to patch the unbound method with a real
729function instead. The :func:`patch` decorator makes it so simple to
730patch out methods with a mock that having to create a real function becomes a
731nuisance.
732
Georg Brandl7ad3df62014-10-31 07:59:37 +0100733If you pass ``autospec=True`` to patch then it does the patching with a
Michael Foord944e02d2012-03-25 23:12:55 +0100734*real* function object. This function object has the same signature as the one
735it is replacing, but delegates to a mock under the hood. You still get your
736mock auto-created in exactly the same way as before. What it means though, is
737that if you use it to patch out an unbound method on a class the mocked
738function will be turned into a bound method if it is fetched from an instance.
Georg Brandl7ad3df62014-10-31 07:59:37 +0100739It will have ``self`` passed in as the first argument, which is exactly what I
Michael Foord944e02d2012-03-25 23:12:55 +0100740wanted:
741
Ezio Melottic9cfcf12013-03-11 09:42:40 +0200742 >>> class Foo:
Michael Foord944e02d2012-03-25 23:12:55 +0100743 ... def foo(self):
744 ... pass
745 ...
746 >>> with patch.object(Foo, 'foo', autospec=True) as mock_foo:
747 ... mock_foo.return_value = 'foo'
748 ... foo = Foo()
749 ... foo.foo()
750 ...
751 'foo'
752 >>> mock_foo.assert_called_once_with(foo)
753
Georg Brandl7ad3df62014-10-31 07:59:37 +0100754If we don't use ``autospec=True`` then the unbound method is patched out
755with a Mock instance instead, and isn't called with ``self``.
Michael Foord944e02d2012-03-25 23:12:55 +0100756
757
758Checking multiple calls with mock
Georg Brandl7fc972a2013-02-03 14:00:04 +0100759~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Michael Foord944e02d2012-03-25 23:12:55 +0100760
761mock has a nice API for making assertions about how your mock objects are used.
762
763 >>> mock = Mock()
764 >>> mock.foo_bar.return_value = None
765 >>> mock.foo_bar('baz', spam='eggs')
766 >>> mock.foo_bar.assert_called_with('baz', spam='eggs')
767
768If your mock is only being called once you can use the
769:meth:`assert_called_once_with` method that also asserts that the
770:attr:`call_count` is one.
771
772 >>> mock.foo_bar.assert_called_once_with('baz', spam='eggs')
773 >>> mock.foo_bar()
774 >>> mock.foo_bar.assert_called_once_with('baz', spam='eggs')
775 Traceback (most recent call last):
776 ...
777 AssertionError: Expected to be called once. Called 2 times.
778
Georg Brandl7ad3df62014-10-31 07:59:37 +0100779Both ``assert_called_with`` and ``assert_called_once_with`` make assertions about
Michael Foord944e02d2012-03-25 23:12:55 +0100780the *most recent* call. If your mock is going to be called several times, and
781you want to make assertions about *all* those calls you can use
782:attr:`~Mock.call_args_list`:
783
784 >>> mock = Mock(return_value=None)
785 >>> mock(1, 2, 3)
786 >>> mock(4, 5, 6)
787 >>> mock()
788 >>> mock.call_args_list
789 [call(1, 2, 3), call(4, 5, 6), call()]
790
791The :data:`call` helper makes it easy to make assertions about these calls. You
Georg Brandl7ad3df62014-10-31 07:59:37 +0100792can build up a list of expected calls and compare it to ``call_args_list``. This
793looks remarkably similar to the repr of the ``call_args_list``:
Michael Foord944e02d2012-03-25 23:12:55 +0100794
795 >>> expected = [call(1, 2, 3), call(4, 5, 6), call()]
796 >>> mock.call_args_list == expected
797 True
798
799
800Coping with mutable arguments
Georg Brandl7fc972a2013-02-03 14:00:04 +0100801~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Michael Foord944e02d2012-03-25 23:12:55 +0100802
803Another situation is rare, but can bite you, is when your mock is called with
Georg Brandl7ad3df62014-10-31 07:59:37 +0100804mutable arguments. ``call_args`` and ``call_args_list`` store *references* to the
Michael Foord944e02d2012-03-25 23:12:55 +0100805arguments. If the arguments are mutated by the code under test then you can no
806longer make assertions about what the values were when the mock was called.
807
808Here's some example code that shows the problem. Imagine the following functions
809defined in 'mymodule'::
810
811 def frob(val):
812 pass
813
814 def grob(val):
815 "First frob and then clear val"
816 frob(val)
817 val.clear()
818
Georg Brandl7ad3df62014-10-31 07:59:37 +0100819When we try to test that ``grob`` calls ``frob`` with the correct argument look
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200820what happens::
Michael Foord944e02d2012-03-25 23:12:55 +0100821
822 >>> with patch('mymodule.frob') as mock_frob:
Serhiy Storchakac02d1882014-12-11 10:28:14 +0200823 ... val = {6}
Michael Foord944e02d2012-03-25 23:12:55 +0100824 ... mymodule.grob(val)
825 ...
826 >>> val
Serhiy Storchakac02d1882014-12-11 10:28:14 +0200827 set()
828 >>> mock_frob.assert_called_with({6})
Michael Foord944e02d2012-03-25 23:12:55 +0100829 Traceback (most recent call last):
830 ...
Serhiy Storchakac02d1882014-12-11 10:28:14 +0200831 AssertionError: Expected: (({6},), {})
832 Called with: ((set(),), {})
Michael Foord944e02d2012-03-25 23:12:55 +0100833
834One possibility would be for mock to copy the arguments you pass in. This
835could then cause problems if you do assertions that rely on object identity
836for equality.
837
838Here's one solution that uses the :attr:`side_effect`
Georg Brandl7ad3df62014-10-31 07:59:37 +0100839functionality. If you provide a ``side_effect`` function for a mock then
840``side_effect`` will be called with the same args as the mock. This gives us an
Michael Foord944e02d2012-03-25 23:12:55 +0100841opportunity to copy the arguments and store them for later assertions. In this
842example I'm using *another* mock to store the arguments so that I can use the
843mock methods for doing the assertion. Again a helper function sets this up for
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200844me. ::
Michael Foord944e02d2012-03-25 23:12:55 +0100845
846 >>> from copy import deepcopy
847 >>> from unittest.mock import Mock, patch, DEFAULT
848 >>> def copy_call_args(mock):
849 ... new_mock = Mock()
850 ... def side_effect(*args, **kwargs):
851 ... args = deepcopy(args)
852 ... kwargs = deepcopy(kwargs)
853 ... new_mock(*args, **kwargs)
854 ... return DEFAULT
855 ... mock.side_effect = side_effect
856 ... return new_mock
857 ...
858 >>> with patch('mymodule.frob') as mock_frob:
859 ... new_mock = copy_call_args(mock_frob)
Serhiy Storchakac02d1882014-12-11 10:28:14 +0200860 ... val = {6}
Michael Foord944e02d2012-03-25 23:12:55 +0100861 ... mymodule.grob(val)
862 ...
Serhiy Storchakac02d1882014-12-11 10:28:14 +0200863 >>> new_mock.assert_called_with({6})
Michael Foord944e02d2012-03-25 23:12:55 +0100864 >>> new_mock.call_args
Serhiy Storchakac02d1882014-12-11 10:28:14 +0200865 call({6})
Michael Foord944e02d2012-03-25 23:12:55 +0100866
Georg Brandl7ad3df62014-10-31 07:59:37 +0100867``copy_call_args`` is called with the mock that will be called. It returns a new
868mock that we do the assertion on. The ``side_effect`` function makes a copy of
869the args and calls our ``new_mock`` with the copy.
Michael Foord944e02d2012-03-25 23:12:55 +0100870
871.. note::
872
873 If your mock is only going to be used once there is an easier way of
874 checking arguments at the point they are called. You can simply do the
Georg Brandl7ad3df62014-10-31 07:59:37 +0100875 checking inside a ``side_effect`` function.
Michael Foord944e02d2012-03-25 23:12:55 +0100876
877 >>> def side_effect(arg):
Serhiy Storchakac02d1882014-12-11 10:28:14 +0200878 ... assert arg == {6}
Michael Foord944e02d2012-03-25 23:12:55 +0100879 ...
880 >>> mock = Mock(side_effect=side_effect)
Serhiy Storchakac02d1882014-12-11 10:28:14 +0200881 >>> mock({6})
Michael Foord944e02d2012-03-25 23:12:55 +0100882 >>> mock(set())
883 Traceback (most recent call last):
884 ...
885 AssertionError
886
Georg Brandl7ad3df62014-10-31 07:59:37 +0100887An alternative approach is to create a subclass of :class:`Mock` or
888:class:`MagicMock` that copies (using :func:`copy.deepcopy`) the arguments.
Michael Foord944e02d2012-03-25 23:12:55 +0100889Here's an example implementation:
890
891 >>> from copy import deepcopy
892 >>> class CopyingMock(MagicMock):
Serhiy Storchaka2085bd02019-06-01 11:00:15 +0300893 ... def __call__(self, /, *args, **kwargs):
Michael Foord944e02d2012-03-25 23:12:55 +0100894 ... args = deepcopy(args)
895 ... kwargs = deepcopy(kwargs)
896 ... return super(CopyingMock, self).__call__(*args, **kwargs)
897 ...
898 >>> c = CopyingMock(return_value=None)
899 >>> arg = set()
900 >>> c(arg)
901 >>> arg.add(1)
902 >>> c.assert_called_with(set())
903 >>> c.assert_called_with(arg)
904 Traceback (most recent call last):
905 ...
Serhiy Storchakac02d1882014-12-11 10:28:14 +0200906 AssertionError: Expected call: mock({1})
907 Actual call: mock(set())
Michael Foord944e02d2012-03-25 23:12:55 +0100908 >>> c.foo
909 <CopyingMock name='mock.foo' id='...'>
910
Georg Brandl7ad3df62014-10-31 07:59:37 +0100911When you subclass ``Mock`` or ``MagicMock`` all dynamically created attributes,
912and the ``return_value`` will use your subclass automatically. That means all
913children of a ``CopyingMock`` will also have the type ``CopyingMock``.
Michael Foord944e02d2012-03-25 23:12:55 +0100914
915
Michael Foord944e02d2012-03-25 23:12:55 +0100916Nesting Patches
Georg Brandl7fc972a2013-02-03 14:00:04 +0100917~~~~~~~~~~~~~~~
Michael Foord944e02d2012-03-25 23:12:55 +0100918
919Using patch as a context manager is nice, but if you do multiple patches you
920can end up with nested with statements indenting further and further to the
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200921right::
Michael Foord944e02d2012-03-25 23:12:55 +0100922
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200923 >>> class MyTest(unittest.TestCase):
Michael Foord944e02d2012-03-25 23:12:55 +0100924 ...
925 ... def test_foo(self):
926 ... with patch('mymodule.Foo') as mock_foo:
927 ... with patch('mymodule.Bar') as mock_bar:
928 ... with patch('mymodule.Spam') as mock_spam:
929 ... assert mymodule.Foo is mock_foo
930 ... assert mymodule.Bar is mock_bar
931 ... assert mymodule.Spam is mock_spam
932 ...
933 >>> original = mymodule.Foo
934 >>> MyTest('test_foo').test_foo()
935 >>> assert mymodule.Foo is original
936
Georg Brandl7ad3df62014-10-31 07:59:37 +0100937With unittest ``cleanup`` functions and the :ref:`start-and-stop` we can
Michael Foord944e02d2012-03-25 23:12:55 +0100938achieve the same effect without the nested indentation. A simple helper
Georg Brandl7ad3df62014-10-31 07:59:37 +0100939method, ``create_patch``, puts the patch in place and returns the created mock
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200940for us::
Michael Foord944e02d2012-03-25 23:12:55 +0100941
Stéphane Wirtel859c0682018-10-12 09:51:05 +0200942 >>> class MyTest(unittest.TestCase):
Michael Foord944e02d2012-03-25 23:12:55 +0100943 ...
944 ... def create_patch(self, name):
945 ... patcher = patch(name)
946 ... thing = patcher.start()
947 ... self.addCleanup(patcher.stop)
948 ... return thing
949 ...
950 ... def test_foo(self):
951 ... mock_foo = self.create_patch('mymodule.Foo')
952 ... mock_bar = self.create_patch('mymodule.Bar')
953 ... mock_spam = self.create_patch('mymodule.Spam')
954 ...
955 ... assert mymodule.Foo is mock_foo
956 ... assert mymodule.Bar is mock_bar
957 ... assert mymodule.Spam is mock_spam
958 ...
959 >>> original = mymodule.Foo
960 >>> MyTest('test_foo').run()
961 >>> assert mymodule.Foo is original
962
963
964Mocking a dictionary with MagicMock
Georg Brandl7fc972a2013-02-03 14:00:04 +0100965~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Michael Foord944e02d2012-03-25 23:12:55 +0100966
967You may want to mock a dictionary, or other container object, recording all
968access to it whilst having it still behave like a dictionary.
969
970We can do this with :class:`MagicMock`, which will behave like a dictionary,
971and using :data:`~Mock.side_effect` to delegate dictionary access to a real
972underlying dictionary that is under our control.
973
Georg Brandl7ad3df62014-10-31 07:59:37 +0100974When the :meth:`__getitem__` and :meth:`__setitem__` methods of our ``MagicMock`` are called
975(normal dictionary access) then ``side_effect`` is called with the key (and in
976the case of ``__setitem__`` the value too). We can also control what is returned.
Michael Foord944e02d2012-03-25 23:12:55 +0100977
Georg Brandl7ad3df62014-10-31 07:59:37 +0100978After the ``MagicMock`` has been used we can use attributes like
Michael Foord944e02d2012-03-25 23:12:55 +0100979:data:`~Mock.call_args_list` to assert about how the dictionary was used:
980
981 >>> my_dict = {'a': 1, 'b': 2, 'c': 3}
982 >>> def getitem(name):
983 ... return my_dict[name]
984 ...
985 >>> def setitem(name, val):
986 ... my_dict[name] = val
987 ...
988 >>> mock = MagicMock()
989 >>> mock.__getitem__.side_effect = getitem
990 >>> mock.__setitem__.side_effect = setitem
991
992.. note::
993
Georg Brandl7ad3df62014-10-31 07:59:37 +0100994 An alternative to using ``MagicMock`` is to use ``Mock`` and *only* provide
Michael Foord944e02d2012-03-25 23:12:55 +0100995 the magic methods you specifically want:
996
997 >>> mock = Mock()
Éric Araujo0b1be1a2014-03-17 16:48:13 -0400998 >>> mock.__getitem__ = Mock(side_effect=getitem)
999 >>> mock.__setitem__ = Mock(side_effect=setitem)
Michael Foord944e02d2012-03-25 23:12:55 +01001000
Georg Brandl7ad3df62014-10-31 07:59:37 +01001001 A *third* option is to use ``MagicMock`` but passing in ``dict`` as the *spec*
1002 (or *spec_set*) argument so that the ``MagicMock`` created only has
Michael Foord944e02d2012-03-25 23:12:55 +01001003 dictionary magic methods available:
1004
1005 >>> mock = MagicMock(spec_set=dict)
1006 >>> mock.__getitem__.side_effect = getitem
1007 >>> mock.__setitem__.side_effect = setitem
1008
Georg Brandl7ad3df62014-10-31 07:59:37 +01001009With these side effect functions in place, the ``mock`` will behave like a normal
1010dictionary but recording the access. It even raises a :exc:`KeyError` if you try
Michael Foord944e02d2012-03-25 23:12:55 +01001011to access a key that doesn't exist.
1012
1013 >>> mock['a']
1014 1
1015 >>> mock['c']
1016 3
1017 >>> mock['d']
1018 Traceback (most recent call last):
1019 ...
1020 KeyError: 'd'
1021 >>> mock['b'] = 'fish'
1022 >>> mock['d'] = 'eggs'
1023 >>> mock['b']
1024 'fish'
1025 >>> mock['d']
1026 'eggs'
1027
1028After it has been used you can make assertions about the access using the normal
1029mock methods and attributes:
1030
1031 >>> mock.__getitem__.call_args_list
1032 [call('a'), call('c'), call('d'), call('b'), call('d')]
1033 >>> mock.__setitem__.call_args_list
1034 [call('b', 'fish'), call('d', 'eggs')]
1035 >>> my_dict
Stéphane Wirtel859c0682018-10-12 09:51:05 +02001036 {'a': 1, 'b': 'fish', 'c': 3, 'd': 'eggs'}
Michael Foord944e02d2012-03-25 23:12:55 +01001037
1038
1039Mock subclasses and their attributes
Georg Brandl7fc972a2013-02-03 14:00:04 +01001040~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Michael Foord944e02d2012-03-25 23:12:55 +01001041
Georg Brandl7ad3df62014-10-31 07:59:37 +01001042There are various reasons why you might want to subclass :class:`Mock`. One
1043reason might be to add helper methods. Here's a silly example:
Michael Foord944e02d2012-03-25 23:12:55 +01001044
1045 >>> class MyMock(MagicMock):
1046 ... def has_been_called(self):
1047 ... return self.called
1048 ...
1049 >>> mymock = MyMock(return_value=None)
1050 >>> mymock
1051 <MyMock id='...'>
1052 >>> mymock.has_been_called()
1053 False
1054 >>> mymock()
1055 >>> mymock.has_been_called()
1056 True
1057
Georg Brandl7ad3df62014-10-31 07:59:37 +01001058The standard behaviour for ``Mock`` instances is that attributes and the return
Michael Foord944e02d2012-03-25 23:12:55 +01001059value mocks are of the same type as the mock they are accessed on. This ensures
Georg Brandl7ad3df62014-10-31 07:59:37 +01001060that ``Mock`` attributes are ``Mocks`` and ``MagicMock`` attributes are ``MagicMocks``
Michael Foord944e02d2012-03-25 23:12:55 +01001061[#]_. So if you're subclassing to add helper methods then they'll also be
1062available on the attributes and return value mock of instances of your
1063subclass.
1064
1065 >>> mymock.foo
1066 <MyMock name='mock.foo' id='...'>
1067 >>> mymock.foo.has_been_called()
1068 False
1069 >>> mymock.foo()
1070 <MyMock name='mock.foo()' id='...'>
1071 >>> mymock.foo.has_been_called()
1072 True
1073
1074Sometimes this is inconvenient. For example, `one user
Sanyam Khurana338cd832018-01-20 05:55:37 +05301075<https://code.google.com/archive/p/mock/issues/105>`_ is subclassing mock to
Michael Foord944e02d2012-03-25 23:12:55 +01001076created a `Twisted adaptor
Serhiy Storchaka6dff0202016-05-07 10:49:07 +03001077<https://twistedmatrix.com/documents/11.0.0/api/twisted.python.components.html>`_.
Michael Foord944e02d2012-03-25 23:12:55 +01001078Having this applied to attributes too actually causes errors.
1079
Georg Brandl7ad3df62014-10-31 07:59:37 +01001080``Mock`` (in all its flavours) uses a method called ``_get_child_mock`` to create
Michael Foord944e02d2012-03-25 23:12:55 +01001081these "sub-mocks" for attributes and return values. You can prevent your
1082subclass being used for attributes by overriding this method. The signature is
Georg Brandl7ad3df62014-10-31 07:59:37 +01001083that it takes arbitrary keyword arguments (``**kwargs``) which are then passed
Michael Foord944e02d2012-03-25 23:12:55 +01001084onto the mock constructor:
1085
1086 >>> class Subclass(MagicMock):
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001087 ... def _get_child_mock(self, /, **kwargs):
Michael Foord944e02d2012-03-25 23:12:55 +01001088 ... return MagicMock(**kwargs)
1089 ...
1090 >>> mymock = Subclass()
1091 >>> mymock.foo
1092 <MagicMock name='mock.foo' id='...'>
1093 >>> assert isinstance(mymock, Subclass)
1094 >>> assert not isinstance(mymock.foo, Subclass)
1095 >>> assert not isinstance(mymock(), Subclass)
1096
1097.. [#] An exception to this rule are the non-callable mocks. Attributes use the
1098 callable variant because otherwise non-callable mocks couldn't have callable
1099 methods.
1100
1101
1102Mocking imports with patch.dict
Georg Brandl7fc972a2013-02-03 14:00:04 +01001103~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Michael Foord944e02d2012-03-25 23:12:55 +01001104
1105One situation where mocking can be hard is where you have a local import inside
1106a function. These are harder to mock because they aren't using an object from
1107the module namespace that we can patch out.
1108
1109Generally local imports are to be avoided. They are sometimes done to prevent
1110circular dependencies, for which there is *usually* a much better way to solve
1111the problem (refactor the code) or to prevent "up front costs" by delaying the
1112import. This can also be solved in better ways than an unconditional local
1113import (store the module as a class or module attribute and only do the import
1114on first use).
1115
Georg Brandl7ad3df62014-10-31 07:59:37 +01001116That aside there is a way to use ``mock`` to affect the results of an import.
1117Importing fetches an *object* from the :data:`sys.modules` dictionary. Note that it
Michael Foord944e02d2012-03-25 23:12:55 +01001118fetches an *object*, which need not be a module. Importing a module for the
1119first time results in a module object being put in `sys.modules`, so usually
1120when you import something you get a module back. This need not be the case
1121however.
1122
1123This means you can use :func:`patch.dict` to *temporarily* put a mock in place
Georg Brandl7ad3df62014-10-31 07:59:37 +01001124in :data:`sys.modules`. Any imports whilst this patch is active will fetch the mock.
Michael Foord944e02d2012-03-25 23:12:55 +01001125When the patch is complete (the decorated function exits, the with statement
Georg Brandl7ad3df62014-10-31 07:59:37 +01001126body is complete or ``patcher.stop()`` is called) then whatever was there
Michael Foord944e02d2012-03-25 23:12:55 +01001127previously will be restored safely.
1128
1129Here's an example that mocks out the 'fooble' module.
1130
Stéphane Wirtel859c0682018-10-12 09:51:05 +02001131 >>> import sys
Michael Foord944e02d2012-03-25 23:12:55 +01001132 >>> mock = Mock()
1133 >>> with patch.dict('sys.modules', {'fooble': mock}):
1134 ... import fooble
1135 ... fooble.blob()
1136 ...
1137 <Mock name='mock.blob()' id='...'>
1138 >>> assert 'fooble' not in sys.modules
1139 >>> mock.blob.assert_called_once_with()
1140
Georg Brandl7ad3df62014-10-31 07:59:37 +01001141As you can see the ``import fooble`` succeeds, but on exit there is no 'fooble'
1142left in :data:`sys.modules`.
Michael Foord944e02d2012-03-25 23:12:55 +01001143
Georg Brandl7ad3df62014-10-31 07:59:37 +01001144This also works for the ``from module import name`` form:
Michael Foord944e02d2012-03-25 23:12:55 +01001145
1146 >>> mock = Mock()
1147 >>> with patch.dict('sys.modules', {'fooble': mock}):
1148 ... from fooble import blob
1149 ... blob.blip()
1150 ...
1151 <Mock name='mock.blob.blip()' id='...'>
1152 >>> mock.blob.blip.assert_called_once_with()
1153
1154With slightly more work you can also mock package imports:
1155
1156 >>> mock = Mock()
1157 >>> modules = {'package': mock, 'package.module': mock.module}
1158 >>> with patch.dict('sys.modules', modules):
1159 ... from package.module import fooble
1160 ... fooble()
1161 ...
1162 <Mock name='mock.module.fooble()' id='...'>
1163 >>> mock.module.fooble.assert_called_once_with()
1164
1165
1166Tracking order of calls and less verbose call assertions
Georg Brandl7fc972a2013-02-03 14:00:04 +01001167~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Michael Foord944e02d2012-03-25 23:12:55 +01001168
1169The :class:`Mock` class allows you to track the *order* of method calls on
1170your mock objects through the :attr:`~Mock.method_calls` attribute. This
1171doesn't allow you to track the order of calls between separate mock objects,
1172however we can use :attr:`~Mock.mock_calls` to achieve the same effect.
1173
Georg Brandl7ad3df62014-10-31 07:59:37 +01001174Because mocks track calls to child mocks in ``mock_calls``, and accessing an
Michael Foord944e02d2012-03-25 23:12:55 +01001175arbitrary attribute of a mock creates a child mock, we can create our separate
1176mocks from a parent one. Calls to those child mock will then all be recorded,
Georg Brandl7ad3df62014-10-31 07:59:37 +01001177in order, in the ``mock_calls`` of the parent:
Michael Foord944e02d2012-03-25 23:12:55 +01001178
1179 >>> manager = Mock()
1180 >>> mock_foo = manager.foo
1181 >>> mock_bar = manager.bar
1182
1183 >>> mock_foo.something()
1184 <Mock name='mock.foo.something()' id='...'>
1185 >>> mock_bar.other.thing()
1186 <Mock name='mock.bar.other.thing()' id='...'>
1187
1188 >>> manager.mock_calls
1189 [call.foo.something(), call.bar.other.thing()]
1190
1191We can then assert about the calls, including the order, by comparing with
Georg Brandl7ad3df62014-10-31 07:59:37 +01001192the ``mock_calls`` attribute on the manager mock:
Michael Foord944e02d2012-03-25 23:12:55 +01001193
1194 >>> expected_calls = [call.foo.something(), call.bar.other.thing()]
1195 >>> manager.mock_calls == expected_calls
1196 True
1197
Georg Brandl7ad3df62014-10-31 07:59:37 +01001198If ``patch`` is creating, and putting in place, your mocks then you can attach
Michael Foord944e02d2012-03-25 23:12:55 +01001199them to a manager mock using the :meth:`~Mock.attach_mock` method. After
Stéphane Wirtel859c0682018-10-12 09:51:05 +02001200attaching calls will be recorded in ``mock_calls`` of the manager. ::
Michael Foord944e02d2012-03-25 23:12:55 +01001201
1202 >>> manager = MagicMock()
1203 >>> with patch('mymodule.Class1') as MockClass1:
1204 ... with patch('mymodule.Class2') as MockClass2:
1205 ... manager.attach_mock(MockClass1, 'MockClass1')
1206 ... manager.attach_mock(MockClass2, 'MockClass2')
1207 ... MockClass1().foo()
1208 ... MockClass2().bar()
Michael Foord944e02d2012-03-25 23:12:55 +01001209 <MagicMock name='mock.MockClass1().foo()' id='...'>
1210 <MagicMock name='mock.MockClass2().bar()' id='...'>
1211 >>> manager.mock_calls
1212 [call.MockClass1(),
Stéphane Wirtel859c0682018-10-12 09:51:05 +02001213 call.MockClass1().foo(),
1214 call.MockClass2(),
1215 call.MockClass2().bar()]
Michael Foord944e02d2012-03-25 23:12:55 +01001216
1217If many calls have been made, but you're only interested in a particular
1218sequence of them then an alternative is to use the
1219:meth:`~Mock.assert_has_calls` method. This takes a list of calls (constructed
1220with the :data:`call` object). If that sequence of calls are in
1221:attr:`~Mock.mock_calls` then the assert succeeds.
1222
1223 >>> m = MagicMock()
1224 >>> m().foo().bar().baz()
1225 <MagicMock name='mock().foo().bar().baz()' id='...'>
1226 >>> m.one().two().three()
1227 <MagicMock name='mock.one().two().three()' id='...'>
1228 >>> calls = call.one().two().three().call_list()
1229 >>> m.assert_has_calls(calls)
1230
Georg Brandl7ad3df62014-10-31 07:59:37 +01001231Even though the chained call ``m.one().two().three()`` aren't the only calls that
Michael Foord944e02d2012-03-25 23:12:55 +01001232have been made to the mock, the assert still succeeds.
1233
1234Sometimes a mock may have several calls made to it, and you are only interested
1235in asserting about *some* of those calls. You may not even care about the
Georg Brandl7ad3df62014-10-31 07:59:37 +01001236order. In this case you can pass ``any_order=True`` to ``assert_has_calls``:
Michael Foord944e02d2012-03-25 23:12:55 +01001237
1238 >>> m = MagicMock()
1239 >>> m(1), m.two(2, 3), m.seven(7), m.fifty('50')
1240 (...)
1241 >>> calls = [call.fifty('50'), call(1), call.seven(7)]
1242 >>> m.assert_has_calls(calls, any_order=True)
1243
1244
1245More complex argument matching
Georg Brandl7fc972a2013-02-03 14:00:04 +01001246~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Michael Foord944e02d2012-03-25 23:12:55 +01001247
1248Using the same basic concept as :data:`ANY` we can implement matchers to do more
1249complex assertions on objects used as arguments to mocks.
1250
1251Suppose we expect some object to be passed to a mock that by default
1252compares equal based on object identity (which is the Python default for user
1253defined classes). To use :meth:`~Mock.assert_called_with` we would need to pass
1254in the exact same object. If we are only interested in some of the attributes
1255of this object then we can create a matcher that will check these attributes
1256for us.
1257
Georg Brandl7ad3df62014-10-31 07:59:37 +01001258You can see in this example how a 'standard' call to ``assert_called_with`` isn't
Michael Foord944e02d2012-03-25 23:12:55 +01001259sufficient:
1260
Ezio Melottic9cfcf12013-03-11 09:42:40 +02001261 >>> class Foo:
Michael Foord944e02d2012-03-25 23:12:55 +01001262 ... def __init__(self, a, b):
1263 ... self.a, self.b = a, b
1264 ...
1265 >>> mock = Mock(return_value=None)
1266 >>> mock(Foo(1, 2))
1267 >>> mock.assert_called_with(Foo(1, 2))
1268 Traceback (most recent call last):
1269 ...
1270 AssertionError: Expected: call(<__main__.Foo object at 0x...>)
1271 Actual call: call(<__main__.Foo object at 0x...>)
1272
Georg Brandl7ad3df62014-10-31 07:59:37 +01001273A comparison function for our ``Foo`` class might look something like this:
Michael Foord944e02d2012-03-25 23:12:55 +01001274
1275 >>> def compare(self, other):
1276 ... if not type(self) == type(other):
1277 ... return False
1278 ... if self.a != other.a:
1279 ... return False
1280 ... if self.b != other.b:
1281 ... return False
1282 ... return True
1283 ...
1284
1285And a matcher object that can use comparison functions like this for its
1286equality operation would look something like this:
1287
Ezio Melottic9cfcf12013-03-11 09:42:40 +02001288 >>> class Matcher:
Michael Foord944e02d2012-03-25 23:12:55 +01001289 ... def __init__(self, compare, some_obj):
1290 ... self.compare = compare
1291 ... self.some_obj = some_obj
1292 ... def __eq__(self, other):
1293 ... return self.compare(self.some_obj, other)
1294 ...
1295
1296Putting all this together:
1297
1298 >>> match_foo = Matcher(compare, Foo(1, 2))
1299 >>> mock.assert_called_with(match_foo)
1300
Georg Brandl7ad3df62014-10-31 07:59:37 +01001301The ``Matcher`` is instantiated with our compare function and the ``Foo`` object
1302we want to compare against. In ``assert_called_with`` the ``Matcher`` equality
Michael Foord944e02d2012-03-25 23:12:55 +01001303method will be called, which compares the object the mock was called with
1304against the one we created our matcher with. If they match then
Georg Brandl7ad3df62014-10-31 07:59:37 +01001305``assert_called_with`` passes, and if they don't an :exc:`AssertionError` is raised:
Michael Foord944e02d2012-03-25 23:12:55 +01001306
1307 >>> match_wrong = Matcher(compare, Foo(3, 4))
1308 >>> mock.assert_called_with(match_wrong)
1309 Traceback (most recent call last):
1310 ...
1311 AssertionError: Expected: ((<Matcher object at 0x...>,), {})
1312 Called with: ((<Foo object at 0x...>,), {})
1313
1314With a bit of tweaking you could have the comparison function raise the
Georg Brandl7ad3df62014-10-31 07:59:37 +01001315:exc:`AssertionError` directly and provide a more useful failure message.
Michael Foord944e02d2012-03-25 23:12:55 +01001316
1317As of version 1.5, the Python testing library `PyHamcrest
Sanyam Khurana338cd832018-01-20 05:55:37 +05301318<https://pyhamcrest.readthedocs.io/>`_ provides similar functionality,
Michael Foord944e02d2012-03-25 23:12:55 +01001319that may be useful here, in the form of its equality matcher
1320(`hamcrest.library.integration.match_equality
Sanyam Khurana338cd832018-01-20 05:55:37 +05301321<https://pyhamcrest.readthedocs.io/en/release-1.8/integration/#module-hamcrest.library.integration.match_equality>`_).