summaryrefslogtreecommitdiff
path: root/docs/index.txt
blob: 02b00ef4f9804c80f5ae5214df9a846c221ce04c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
====================================
 Mock - Mocking and Testing Library
====================================

.. currentmodule:: mock

:Author: `Michael Foord
 <http://www.voidspace.org.uk/python/weblog/index.shtml>`_
:Version: |release|
:Date: 2012/02/13
:Homepage: `Mock Homepage`_
:Download: `Mock on PyPI`_
:Documentation: `PDF Documentation
 <http://www.voidspace.org.uk/downloads/mock-0.8.0.pdf>`_
:License: `BSD License`_
:Support: `Mailing list (testing-in-python@lists.idyll.org)
 <http://lists.idyll.org/listinfo/testing-in-python>`_
:Issue tracker: `Google code project
 <http://code.google.com/p/mock/issues/list>`_

.. _Mock Homepage: http://www.voidspace.org.uk/python/mock/
.. _BSD License: http://www.voidspace.org.uk/python/license.shtml


.. currentmodule:: mock

.. module:: mock
   :synopsis: Mock object and testing library.

.. index:: introduction

mock is a library for testing in Python. It allows you to replace parts of
your system under test with mock objects and make assertions about how they
have been used.

mock provides a core :class:`Mock` class removing the need to create a host
of stubs throughout your test suite. After performing an action, you can make
assertions about which methods / attributes were used and arguments they were
called with. You can also specify return values and set needed attributes in
the normal way.

Additionally, mock provides a :func:`patch` decorator that handles patching
module and class level attributes within the scope of a test, along with
:const:`sentinel` for creating unique objects. See the `quick guide`_ for
some examples of how to use :class:`Mock`, :class:`MagicMock` and
:func:`patch`.

Mock is very easy to use and is designed for use with
`unittest <http://pypi.python.org/pypi/unittest2>`_. Mock is based on
the 'action -> assertion' pattern instead of `'record -> replay'` used by many
mocking frameworks.

mock is tested on Python versions 2.4-2.7, Python 3 plus the latest versions of
Jython and PyPy.


.. testsetup::

   class ProductionClass(object):
      def method(self, *args):
         pass

   module = sys.modules['module'] = ProductionClass
   ProductionClass.ClassName1 = ProductionClass
   ProductionClass.ClassName2 = ProductionClass



API Documentation
=================

.. toctree::
   :maxdepth: 2

   mock
   patch
   helpers
   sentinel
   magicmock
   mocksignature


User Guide
==========

.. toctree::
   :maxdepth: 2

   getting-started
   examples
   compare
   changelog


.. index:: installing

Installing
==========

The current version is |release|. Mock is stable and widely used. If you do
find any bugs, or have suggestions for improvements / extensions
then please contact us.

* `mock on PyPI <http://pypi.python.org/pypi/mock>`_
* `mock documentation as PDF
  <http://www.voidspace.org.uk/downloads/mock-0.8.0.pdf>`_
* `Google Code Home & Mercurial Repository <http://code.google.com/p/mock/>`_

.. index:: repository
.. index:: hg

You can checkout the latest development version from the Google Code Mercurial
repository with the following command:

    ``hg clone https://mock.googlecode.com/hg/ mock``


.. index:: pip
.. index:: easy_install
.. index:: setuptools

If you have pip, setuptools or distribute you can install mock with:

    | ``easy_install -U mock``
    | ``pip install -U mock``

Alternatively you can download the mock distribution from PyPI and after
unpacking run:

   ``python setup.py install``


Quick Guide
===========

:class:`Mock` and :class:`MagicMock` objects create all attributes and
methods as you access them and store details of how they have been used. You
can configure them, to specify return values or limit what attributes are
available, and then make assertions about how they have been used:

.. doctest::

    >>> from mock import MagicMock
    >>> thing = ProductionClass()
    >>> thing.method = MagicMock(return_value=3)
    >>> thing.method(3, 4, 5, key='value')
    3
    >>> thing.method.assert_called_with(3, 4, 5, key='value')

:attr:`side_effect` allows you to perform side effects, including raising an
exception when a mock is called:

.. doctest::

   >>> mock = Mock(side_effect=KeyError('foo'))
   >>> mock()
   Traceback (most recent call last):
    ...
   KeyError: 'foo'

   >>> values = {'a': 1, 'b': 2, 'c': 3}
   >>> def side_effect(arg):
   ...     return values[arg]
   ...
   >>> mock.side_effect = side_effect
   >>> mock('a'), mock('b'), mock('c')
   (1, 2, 3)
   >>> mock.side_effect = [5, 4, 3, 2, 1]
   >>> mock(), mock(), mock()
   (5, 4, 3)

Mock has many other ways you can configure it and control its behaviour. For
example the `spec` argument configures the mock to take its specification
from another object. Attempting to access attributes or methods on the mock
that don't exist on the spec will fail with an `AttributeError`.

The :func:`patch` decorator / context manager makes it easy to mock classes or
objects in a module under test. The object you specify will be replaced with a
mock (or other object) during the test and restored when the test ends:

.. doctest::

    >>> from mock import patch
    >>> @patch('module.ClassName2')
    ... @patch('module.ClassName1')
    ... def test(MockClass1, MockClass2):
    ...     module.ClassName1()
    ...     module.ClassName2()

    ...     assert MockClass1 is module.ClassName1
    ...     assert MockClass2 is module.ClassName2
    ...     assert MockClass1.called
    ...     assert MockClass2.called
    ...
    >>> test()

.. note::

   When you nest patch decorators the mocks are passed in to the decorated
   function in the same order they applied (the normal *python* order that
   decorators are applied). This means from the bottom up, so in the example
   above the mock for `module.ClassName1` is passed in first.

   With `patch` it matters that you patch objects in the namespace where they
   are looked up. This is normally straightforward, but for a quick guide
   read :ref:`where to patch <where-to-patch>`.

As well as a decorator `patch` can be used as a context manager in a with
statement:

.. doctest::

    >>> with patch.object(ProductionClass, 'method', return_value=None) as mock_method:
    ...     thing = ProductionClass()
    ...     thing.method(1, 2, 3)
    ...
    >>> mock_method.assert_called_once_with(1, 2, 3)


There is also :func:`patch.dict` for setting values in a dictionary just
during a scope and restoring the dictionary to its original state when the test
ends:

.. doctest::

   >>> foo = {'key': 'value'}
   >>> original = foo.copy()
   >>> with patch.dict(foo, {'newkey': 'newvalue'}, clear=True):
   ...     assert foo == {'newkey': 'newvalue'}
   ...
   >>> assert foo == original

Mock supports the mocking of Python :ref:`magic methods <magic-methods>`. The
easiest way of using magic methods is with the :class:`MagicMock` class. It
allows you to do things like:

.. doctest::

    >>> mock = MagicMock()
    >>> mock.__str__.return_value = 'foobarbaz'
    >>> str(mock)
    'foobarbaz'
    >>> mock.__str__.assert_called_with()

Mock allows you to assign functions (or other Mock instances) to magic methods
and they will be called appropriately. The `MagicMock` class is just a Mock
variant that has all of the magic methods pre-created for you (well, all the
useful ones anyway).

The following is an example of using magic methods with the ordinary Mock
class:

.. doctest::

    >>> mock = Mock()
    >>> mock.__str__ = Mock(return_value='wheeeeee')
    >>> str(mock)
    'wheeeeee'

For ensuring that the mock objects in your tests have the same api as the
objects they are replacing, you can use :ref:`auto-speccing <auto-speccing>`.
Auto-speccing can be done through the `autospec` argument to patch, or the
:func:`create_autospec` function. Auto-speccing creates mock objects that
have the same attributes and methods as the objects they are replacing, and
any functions and methods (including constructors) have the same call
signature as the real object.

This ensures that your mocks will fail in the same way as your production
code if they are used incorrectly:

.. doctest::

   >>> from mock import create_autospec
   >>> def function(a, b, c):
   ...     pass
   ...
   >>> mock_function = create_autospec(function, return_value='fishy')
   >>> mock_function(1, 2, 3)
   'fishy'
   >>> mock_function.assert_called_once_with(1, 2, 3)
   >>> mock_function('wrong arguments')
   Traceback (most recent call last):
    ...
   TypeError: <lambda>() takes exactly 3 arguments (1 given)

`create_autospec` can also be used on classes, where it copies the signature of
the `__init__` method, and on callable objects where it copies the signature of
the `__call__` method.


.. index:: references
.. index:: articles

References
==========

Articles and blog entries on testing with Mock:

* `mock-django: tools for mocking the Django ORM and models
  <https://github.com/dcramer/mock-django>`_
* `PyCon 2011 Video: Testing with mock <https://blip.tv/file/4881513>`_
* `Python: Injecting Mock Objects for Powerful Testing
  <http://blueprintforge.com/blog/2012/01/08/python-injecting-mock-objects-for-powerful-testing/>`_
* `Mocking Django <http://www.mattjmorrison.com/2011/09/mocking-django.html>`_
* `Mocking dates and other classes that can't be modified
  <http://williamjohnbert.com/2011/07/how-to-unit-testing-in-django-with-mocking-and-patching/>`_
* `Mock recipes <http://konryd.blogspot.com/2010/06/mock-recipies.html>`_
* `Mockity mock mock - some love for the mock module
  <http://konryd.blogspot.com/2010/05/mockity-mock-mock-some-love-for-mock.html>`_
* `Coverage and Mock (with django)
  <http://mattsnider.com/python/mock-and-coverage/>`_
* `Python Unit Testing with Mock <http://www.insomnihack.com/?p=194>`_
* `Getting started with Python Mock
  <http://myadventuresincoding.wordpress.com/2011/02/26/python-python-mock-cheat-sheet/>`_
* `Python mock testing techniques and tools
  <http://agiletesting.blogspot.com/2009/07/python-mock-testing-techniques-and.html>`_
* `How To Test Django Template Tags
  <http://techblog.ironfroggy.com/2008/10/how-to-test.html>`_
* `A presentation on Unit Testing with Mock
  <http://pypap.blogspot.com/2008/10/newbie-nugget-unit-testing-with-mock.html>`_
* `Mocking with Django and Google AppEngine
  <http://michael-a-nelson.blogspot.com/2008/09/mocking-with-django-and-google-app.html>`_


.. index:: tests
.. index:: unittest2

Tests
=====

Mock uses `unittest2 <http://pypi.python.org/pypi/unittest2>`_ for its own
test suite. In order to run it, use the `unit2` script that comes with
`unittest2` module on a checkout of the source repository:

   `unit2 discover`

If you have `setuptools <http://pypi.python.org/pypi/distribute>`_ as well as
unittest2 you can run:

   ``python setup.py test``

On Python 3.2 you can use ``unittest`` module from the standard library.

   ``python3.2 -m unittest discover``

.. index:: Python 3

On Python 3 the tests for unicode are skipped as they are not relevant. On
Python 2.4 tests that use the with statements are skipped as the with statement
is invalid syntax on Python 2.4.


.. index:: older versions

Older Versions
==============

Documentation for older versions of mock:

* `mock 0.7 <http://www.voidspace.org.uk/python/mock/0.7/>`_
* `mock 0.6 <http://www.voidspace.org.uk/python/mock/0.6.0/>`_

Docs from the in-development version of `mock` can be found at
`mock.readthedocs.org <http://mock.readthedocs.org>`_.


Terminology
===========

Terminology for objects used to replace other ones can be confusing. Terms
like double, fake, mock, stub, and spy are all used with varying meanings.

In `classic mock terminology
<http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html>`_
:class:`mock.Mock` is a `spy <http://xunitpatterns.com/Test%20Spy.html>`_ that
allows for *post-mortem* examination. This is what I call the "action ->
assertion" [#]_ pattern of testing.

I'm not however a fan of this "statically typed mocking terminology"
promulgated by `Martin Fowler
<http://martinfowler.com/articles/mocksArentStubs.html>`_. It confuses usage
patterns with implementation and prevents you from using natural terminology
when discussing mocking.

I much prefer duck typing, if an object used in your test suite looks like a
mock object and quacks like a mock object then it's fine to call it a mock, no
matter what the implementation looks like.

This terminology is perhaps more useful in less capable languages where
different usage patterns will *require* different implementations.
`mock.Mock()` is capable of being used in most of the different roles
described by Fowler, except (annoyingly / frustratingly / ironically) a Mock
itself!

How about a simpler definition: a "mock object" is an object used to replace a
real one in a system under test.

.. [#] This pattern is called "AAA" by some members of the testing community;
   "Arrange - Act - Assert".