blob: 1b5d289ebe83908e87388f71b40b0e94ab1efa66 [file] [log] [blame]
Michael Foord1e68bec2012-03-03 22:24:30 +00001===========================
2 Getting Started with Mock
3===========================
4
5.. _getting-started:
6
7.. index:: Getting Started
8
9.. testsetup::
10
11 class SomeClass(object):
12 static_method = None
13 class_method = None
14 attribute = None
15
16 sys.modules['package'] = package = Mock(name='package')
17 sys.modules['package.module'] = module = package.module
18 sys.modules['module'] = package.module
19
20
21Using Mock
22==========
23
24Mock Patching Methods
25---------------------
26
27Common uses for :class:`Mock` objects include:
28
29* Patching methods
30* Recording method calls on objects
31
32You might want to replace a method on an object to check that
33it is called with the correct arguments by another part of the system:
34
35.. doctest::
36
37 >>> real = SomeClass()
38 >>> real.method = MagicMock(name='method')
39 >>> real.method(3, 4, 5, key='value')
40 <MagicMock name='method()' id='...'>
41
42Once our mock has been used (`real.method` in this example) it has methods
43and attributes that allow you to make assertions about how it has been used.
44
45.. note::
46
47 In most of these examples the :class:`Mock` and :class:`MagicMock` classes
48 are interchangeable. As the `MagicMock` is the more capable class it makes
49 a sensible one to use by default.
50
51Once the mock has been called its :attr:`~Mock.called` attribute is set to
52`True`. More importantly we can use the :meth:`~Mock.assert_called_with` or
Michael Foord06d4f2e2012-04-13 20:43:06 +010053:meth:`~Mock.assert_called_once_with` method to check that it was called with
Michael Foord1e68bec2012-03-03 22:24:30 +000054the correct arguments.
55
56This example tests that calling `ProductionClass().method` results in a call to
57the `something` method:
58
59.. doctest::
60
61 >>> from mock import MagicMock
62 >>> class ProductionClass(object):
63 ... 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
83The simple `ProductionClass` below has a `closer` method. If it is called with
84an object then it calls `close` on it.
85
86.. doctest::
87
88 >>> class ProductionClass(object):
89 ... def closer(self, something):
90 ... something.close()
91 ...
92
93So to test it we need to pass in an object with a `close` method and check
94that it was called correctly.
95
96.. doctest::
97
98 >>> real = ProductionClass()
99 >>> mock = Mock()
100 >>> real.closer(mock)
101 >>> mock.close.assert_called_with()
102
103We don't have to do any work to provide the 'close' method on our mock.
104Accessing close creates it. So, if 'close' hasn't already been called then
105accessing it in the test will create it, but :meth:`~Mock.assert_called_with`
106will raise a failure exception.
107
108
109Mocking Classes
110---------------
111
112A common use case is to mock out classes instantiated by your code under test.
113When you patch a class, then that class is replaced with a mock. Instances
114are created by *calling the class*. This means you access the "mock instance"
115by looking at the return value of the mocked class.
116
117In the example below we have a function `some_function` that instantiates `Foo`
118and calls a method on it. The call to `patch` replaces the class `Foo` with a
119mock. The `Foo` instance is the result of calling the mock, so it is configured
Michael Foord06d4f2e2012-04-13 20:43:06 +0100120by modifying the mock :attr:`~Mock.return_value`.
Michael Foord1e68bec2012-03-03 22:24:30 +0000121
122.. doctest::
123
124 >>> def some_function():
125 ... instance = module.Foo()
126 ... return instance.method()
127 ...
128 >>> with patch('module.Foo') as mock:
129 ... instance = mock.return_value
130 ... instance.method.return_value = 'the result'
131 ... result = some_function()
132 ... assert result == 'the result'
133
134
135Naming your mocks
136-----------------
137
138It can be useful to give your mocks a name. The name is shown in the repr of
139the mock and can be helpful when the mock appears in test failure messages. The
140name is also propagated to attributes or methods of the mock:
141
142.. doctest::
143
144 >>> mock = MagicMock(name='foo')
145 >>> mock
146 <MagicMock name='foo' id='...'>
147 >>> mock.method
148 <MagicMock name='foo.method' id='...'>
149
150
151Tracking all Calls
152------------------
153
154Often you want to track more than a single call to a method. The
155:attr:`~Mock.mock_calls` attribute records all calls
156to child attributes of the mock - and also to their children.
157
158.. doctest::
159
160 >>> mock = MagicMock()
161 >>> mock.method()
162 <MagicMock name='mock.method()' id='...'>
163 >>> mock.attribute.method(10, x=53)
164 <MagicMock name='mock.attribute.method()' id='...'>
165 >>> mock.mock_calls
166 [call.method(), call.attribute.method(10, x=53)]
167
168If you make an assertion about `mock_calls` and any unexpected methods
169have been called, then the assertion will fail. This is useful because as well
170as asserting that the calls you expected have been made, you are also checking
171that they were made in the right order and with no additional calls:
172
173You use the :data:`call` object to construct lists for comparing with
174`mock_calls`:
175
176.. doctest::
177
178 >>> expected = [call.method(), call.attribute.method(10, x=53)]
179 >>> mock.mock_calls == expected
180 True
181
182
183Setting Return Values and Attributes
184------------------------------------
185
186Setting the return values on a mock object is trivially easy:
187
188.. doctest::
189
190 >>> mock = Mock()
191 >>> mock.return_value = 3
192 >>> mock()
193 3
194
195Of course you can do the same for methods on the mock:
196
197.. doctest::
198
199 >>> mock = Mock()
200 >>> mock.method.return_value = 3
201 >>> mock.method()
202 3
203
204The return value can also be set in the constructor:
205
206.. doctest::
207
208 >>> mock = Mock(return_value=3)
209 >>> mock()
210 3
211
212If you need an attribute setting on your mock, just do it:
213
214.. doctest::
215
216 >>> mock = Mock()
217 >>> mock.x = 3
218 >>> mock.x
219 3
220
221Sometimes you want to mock up a more complex situation, like for example
222`mock.connection.cursor().execute("SELECT 1")`. If we wanted this call to
223return a list, then we have to configure the result of the nested call.
224
225We can use :data:`call` to construct the set of calls in a "chained call" like
226this for easy assertion afterwards:
227
228
229.. doctest::
230
231 >>> mock = Mock()
232 >>> cursor = mock.connection.cursor.return_value
233 >>> cursor.execute.return_value = ['foo']
234 >>> mock.connection.cursor().execute("SELECT 1")
235 ['foo']
236 >>> expected = call.connection.cursor().execute("SELECT 1").call_list()
237 >>> mock.mock_calls
238 [call.connection.cursor(), call.connection.cursor().execute('SELECT 1')]
239 >>> mock.mock_calls == expected
240 True
241
242It is the call to `.call_list()` that turns our call object into a list of
243calls representing the chained calls.
244
245
246
247Raising exceptions with mocks
248-----------------------------
249
250A useful attribute is :attr:`~Mock.side_effect`. If you set this to an
251exception class or instance then the exception will be raised when the mock
252is called.
253
254.. doctest::
255
256 >>> mock = Mock(side_effect=Exception('Boom!'))
257 >>> mock()
258 Traceback (most recent call last):
259 ...
260 Exception: Boom!
261
262
263Side effect functions and iterables
264-----------------------------------
265
266`side_effect` can also be set to a function or an iterable. The use case for
267`side_effect` as an iterable is where your mock is going to be called several
268times, and you want each call to return a different value. When you set
269`side_effect` to an iterable every call to the mock returns the next value
270from the iterable:
271
272.. doctest::
273
274 >>> mock = MagicMock(side_effect=[4, 5, 6])
275 >>> mock()
276 4
277 >>> mock()
278 5
279 >>> mock()
280 6
281
282
283For more advanced use cases, like dynamically varying the return values
284depending on what the mock is called with, `side_effect` can be a function.
285The function will be called with the same arguments as the mock. Whatever the
286function returns is what the call returns:
287
288.. doctest::
289
290 >>> vals = {(1, 2): 1, (2, 3): 2}
291 >>> def side_effect(*args):
292 ... return vals[args]
293 ...
294 >>> mock = MagicMock(side_effect=side_effect)
295 >>> mock(1, 2)
296 1
297 >>> mock(2, 3)
298 2
299
300
301Creating a Mock from an Existing Object
302---------------------------------------
303
304One problem with over use of mocking is that it couples your tests to the
305implementation of your mocks rather than your real code. Suppose you have a
306class that implements `some_method`. In a test for another class, you
307provide a mock of this object that *also* provides `some_method`. If later
308you refactor the first class, so that it no longer has `some_method` - then
309your tests will continue to pass even though your code is now broken!
310
311`Mock` allows you to provide an object as a specification for the mock,
312using the `spec` keyword argument. Accessing methods / attributes on the
313mock that don't exist on your specification object will immediately raise an
314attribute error. If you change the implementation of your specification, then
315tests that use that class will start failing immediately without you having to
316instantiate the class in those tests.
317
318.. doctest::
319
320 >>> mock = Mock(spec=SomeClass)
321 >>> mock.old_method()
322 Traceback (most recent call last):
323 ...
324 AttributeError: object has no attribute 'old_method'
325
326If you want a stronger form of specification that prevents the setting
327of arbitrary attributes as well as the getting of them then you can use
328`spec_set` instead of `spec`.
329
330
331
332Patch Decorators
333================
334
335.. note::
336
337 With `patch` it matters that you patch objects in the namespace where they
338 are looked up. This is normally straightforward, but for a quick guide
339 read :ref:`where to patch <where-to-patch>`.
340
341
342A common need in tests is to patch a class attribute or a module attribute,
343for example patching a builtin or patching a class in a module to test that it
344is instantiated. Modules and classes are effectively global, so patching on
345them has to be undone after the test or the patch will persist into other
346tests and cause hard to diagnose problems.
347
348mock provides three convenient decorators for this: `patch`, `patch.object` and
349`patch.dict`. `patch` takes a single string, of the form
350`package.module.Class.attribute` to specify the attribute you are patching. It
351also optionally takes a value that you want the attribute (or class or
352whatever) to be replaced with. 'patch.object' takes an object and the name of
353the attribute you would like patched, plus optionally the value to patch it
354with.
355
356`patch.object`:
357
358.. doctest::
359
360 >>> original = SomeClass.attribute
361 >>> @patch.object(SomeClass, 'attribute', sentinel.attribute)
362 ... def test():
363 ... assert SomeClass.attribute == sentinel.attribute
364 ...
365 >>> test()
366 >>> assert SomeClass.attribute == original
367
368 >>> @patch('package.module.attribute', sentinel.attribute)
369 ... def test():
370 ... from package.module import attribute
371 ... assert attribute is sentinel.attribute
372 ...
373 >>> test()
374
375If you are patching a module (including `__builtin__`) then use `patch`
376instead of `patch.object`:
377
378.. doctest::
379
380 >>> mock = MagicMock(return_value = sentinel.file_handle)
381 >>> with patch('__builtin__.open', mock):
382 ... handle = open('filename', 'r')
383 ...
384 >>> mock.assert_called_with('filename', 'r')
385 >>> assert handle == sentinel.file_handle, "incorrect file handle returned"
386
387The module name can be 'dotted', in the form `package.module` if needed:
388
389.. doctest::
390
391 >>> @patch('package.module.ClassName.attribute', sentinel.attribute)
392 ... def test():
393 ... from package.module import ClassName
394 ... assert ClassName.attribute == sentinel.attribute
395 ...
396 >>> test()
397
398A nice pattern is to actually decorate test methods themselves:
399
400.. doctest::
401
402 >>> class MyTest(unittest2.TestCase):
403 ... @patch.object(SomeClass, 'attribute', sentinel.attribute)
404 ... def test_something(self):
405 ... self.assertEqual(SomeClass.attribute, sentinel.attribute)
406 ...
407 >>> original = SomeClass.attribute
408 >>> MyTest('test_something').test_something()
409 >>> assert SomeClass.attribute == original
410
411If you want to patch with a Mock, you can use `patch` with only one argument
412(or `patch.object` with two arguments). The mock will be created for you and
413passed into the test function / method:
414
415.. doctest::
416
417 >>> class MyTest(unittest2.TestCase):
418 ... @patch.object(SomeClass, 'static_method')
419 ... def test_something(self, mock_method):
420 ... SomeClass.static_method()
421 ... mock_method.assert_called_with()
422 ...
423 >>> MyTest('test_something').test_something()
424
425You can stack up multiple patch decorators using this pattern:
426
427.. doctest::
428
429 >>> class MyTest(unittest2.TestCase):
430 ... @patch('package.module.ClassName1')
431 ... @patch('package.module.ClassName2')
432 ... def test_something(self, MockClass2, MockClass1):
433 ... self.assertTrue(package.module.ClassName1 is MockClass1)
434 ... self.assertTrue(package.module.ClassName2 is MockClass2)
435 ...
436 >>> MyTest('test_something').test_something()
437
438When you nest patch decorators the mocks are passed in to the decorated
439function in the same order they applied (the normal *python* order that
440decorators are applied). This means from the bottom up, so in the example
441above the mock for `test_module.ClassName2` is passed in first.
442
443There is also :func:`patch.dict` for setting values in a dictionary just
444during a scope and restoring the dictionary to its original state when the test
445ends:
446
447.. doctest::
448
449 >>> foo = {'key': 'value'}
450 >>> original = foo.copy()
451 >>> with patch.dict(foo, {'newkey': 'newvalue'}, clear=True):
452 ... assert foo == {'newkey': 'newvalue'}
453 ...
454 >>> assert foo == original
455
456`patch`, `patch.object` and `patch.dict` can all be used as context managers.
457
458Where you use `patch` to create a mock for you, you can get a reference to the
459mock using the "as" form of the with statement:
460
461.. doctest::
462
463 >>> class ProductionClass(object):
464 ... def method(self):
465 ... pass
466 ...
467 >>> with patch.object(ProductionClass, 'method') as mock_method:
468 ... mock_method.return_value = None
469 ... real = ProductionClass()
470 ... real.method(1, 2, 3)
471 ...
472 >>> mock_method.assert_called_with(1, 2, 3)
473
474
475As an alternative `patch`, `patch.object` and `patch.dict` can be used as
476class decorators. When used in this way it is the same as applying the
477decorator indvidually to every method whose name starts with "test".
478
479For some more advanced examples, see the :ref:`further-examples` page.