blob: d668fb760b1c4344a28e0ed33618fc48ad1e3474 [file] [log] [blame]
Michael Foord1e68bec2012-03-03 22:24:30 +00001mock is a library for testing in Python. It allows you to replace parts of
2your system under test with mock objects and make assertions about how they
3have been used.
4
5mock provides a core `MagicMock` class removing the need to create a host of
6stubs throughout your test suite. After performing an action, you can make
7assertions about which methods / attributes were used and arguments they were
8called with. You can also specify return values and set needed attributes in
9the normal way.
10
11mock is tested on Python versions 2.4-2.7 and Python 3. mock is also tested
12with the latest versions of Jython and pypy.
13
14The mock module also provides utility functions / objects to assist with
15testing, particularly monkey patching.
16
17* `PDF documentation for 0.8.0
18 <http://www.voidspace.org.uk/downloads/mock-0.8.0.pdf>`_
19* `mock on google code (repository and issue tracker)
20 <http://code.google.com/p/mock/>`_
21* `mock documentation
22 <http://www.voidspace.org.uk/python/mock/>`_
23* `mock on PyPI <http://pypi.python.org/pypi/mock/>`_
24* `Mailing list (testing-in-python@lists.idyll.org)
25 <http://lists.idyll.org/listinfo/testing-in-python>`_
26
27Mock is very easy to use and is designed for use with
28`unittest <http://pypi.python.org/pypi/unittest2>`_. Mock is based on
29the 'action -> assertion' pattern instead of 'record -> replay' used by many
30mocking frameworks. See the `mock documentation`_ for full details.
31
32Mock objects create all attributes and methods as you access them and store
33details of how they have been used. You can configure them, to specify return
34values or limit what attributes are available, and then make assertions about
35how they have been used::
36
37 >>> from mock import Mock
38 >>> real = ProductionClass()
39 >>> real.method = Mock(return_value=3)
40 >>> real.method(3, 4, 5, key='value')
41 3
42 >>> real.method.assert_called_with(3, 4, 5, key='value')
43
44`side_effect` allows you to perform side effects, return different values or
45raise an exception when a mock is called::
46
47 >>> mock = Mock(side_effect=KeyError('foo'))
48 >>> mock()
49 Traceback (most recent call last):
50 ...
51 KeyError: 'foo'
52 >>> values = {'a': 1, 'b': 2, 'c': 3}
53 >>> def side_effect(arg):
54 ... return values[arg]
55 ...
56 >>> mock.side_effect = side_effect
57 >>> mock('a'), mock('b'), mock('c')
58 (3, 2, 1)
59 >>> mock.side_effect = [5, 4, 3, 2, 1]
60 >>> mock(), mock(), mock()
61 (5, 4, 3)
62
63Mock has many other ways you can configure it and control its behaviour. For
64example the `spec` argument configures the mock to take its specification from
65another object. Attempting to access attributes or methods on the mock that
66don't exist on the spec will fail with an `AttributeError`.
67
68The `patch` decorator / context manager makes it easy to mock classes or
69objects in a module under test. The object you specify will be replaced with a
70mock (or other object) during the test and restored when the test ends::
71
72 >>> from mock import patch
73 >>> @patch('test_module.ClassName1')
74 ... @patch('test_module.ClassName2')
75 ... def test(MockClass2, MockClass1):
76 ... test_module.ClassName1()
77 ... test_module.ClassName2()
78
79 ... assert MockClass1.called
80 ... assert MockClass2.called
81 ...
82 >>> test()
83
84.. note::
85
86 When you nest patch decorators the mocks are passed in to the decorated
87 function in the same order they applied (the normal *python* order that
88 decorators are applied). This means from the bottom up, so in the example
89 above the mock for `test_module.ClassName2` is passed in first.
90
91 With `patch` it matters that you patch objects in the namespace where they
92 are looked up. This is normally straightforward, but for a quick guide
93 read `where to patch
94 <http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch>`_.
95
96As well as a decorator `patch` can be used as a context manager in a with
97statement::
98
99 >>> with patch.object(ProductionClass, 'method') as mock_method:
100 ... mock_method.return_value = None
101 ... real = ProductionClass()
102 ... real.method(1, 2, 3)
103 ...
104 >>> mock_method.assert_called_once_with(1, 2, 3)
105
106There is also `patch.dict` for setting values in a dictionary just during the
107scope of a test and restoring the dictionary to its original state when the
108test ends::
109
110 >>> foo = {'key': 'value'}
111 >>> original = foo.copy()
112 >>> with patch.dict(foo, {'newkey': 'newvalue'}, clear=True):
113 ... assert foo == {'newkey': 'newvalue'}
114 ...
115 >>> assert foo == original
116
117Mock supports the mocking of Python magic methods. The easiest way of
118using magic methods is with the `MagicMock` class. It allows you to do
119things like::
120
121 >>> from mock import MagicMock
122 >>> mock = MagicMock()
123 >>> mock.__str__.return_value = 'foobarbaz'
124 >>> str(mock)
125 'foobarbaz'
126 >>> mock.__str__.assert_called_once_with()
127
128Mock allows you to assign functions (or other Mock instances) to magic methods
129and they will be called appropriately. The MagicMock class is just a Mock
130variant that has all of the magic methods pre-created for you (well - all the
131useful ones anyway).
132
133The following is an example of using magic methods with the ordinary Mock
134class::
135
136 >>> from mock import Mock
137 >>> mock = Mock()
138 >>> mock.__str__ = Mock(return_value = 'wheeeeee')
139 >>> str(mock)
140 'wheeeeee'
141
142For ensuring that the mock objects your tests use have the same api as the
143objects they are replacing, you can use "auto-speccing". Auto-speccing can
144be done through the `autospec` argument to patch, or the `create_autospec`
145function. Auto-speccing creates mock objects that have the same attributes
146and methods as the objects they are replacing, and any functions and methods
147(including constructors) have the same call signature as the real object.
148
149This ensures that your mocks will fail in the same way as your production
150code if they are used incorrectly::
151
152 >>> from mock import create_autospec
153 >>> def function(a, b, c):
154 ... pass
155 ...
156 >>> mock_function = create_autospec(function, return_value='fishy')
157 >>> mock_function(1, 2, 3)
158 'fishy'
159 >>> mock_function.assert_called_once_with(1, 2, 3)
160 >>> mock_function('wrong arguments')
161 Traceback (most recent call last):
162 ...
163 TypeError: <lambda>() takes exactly 3 arguments (1 given)
164
165`create_autospec` can also be used on classes, where it copies the signature of
166the `__init__` method, and on callable objects where it copies the signature of
167the `__call__` method.
168
169The distribution contains tests and documentation. The tests require
170`unittest2 <http://pypi.python.org/pypi/unittest2>`_ to run.
171
172Docs from the in-development version of `mock` can be found at
173`mock.readthedocs.org <http://mock.readthedocs.org>`_.