Michael Foord | 1e68bec | 2012-03-03 22:24:30 +0000 | [diff] [blame] | 1 | mock is a library for testing in Python. It allows you to replace parts of |
| 2 | your system under test with mock objects and make assertions about how they |
| 3 | have been used. |
| 4 | |
| 5 | mock provides a core `MagicMock` class removing the need to create a host of |
| 6 | stubs throughout your test suite. After performing an action, you can make |
| 7 | assertions about which methods / attributes were used and arguments they were |
| 8 | called with. You can also specify return values and set needed attributes in |
| 9 | the normal way. |
| 10 | |
| 11 | mock is tested on Python versions 2.4-2.7 and Python 3. mock is also tested |
| 12 | with the latest versions of Jython and pypy. |
| 13 | |
| 14 | The mock module also provides utility functions / objects to assist with |
| 15 | testing, 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 | |
| 27 | Mock is very easy to use and is designed for use with |
| 28 | `unittest <http://pypi.python.org/pypi/unittest2>`_. Mock is based on |
| 29 | the 'action -> assertion' pattern instead of 'record -> replay' used by many |
| 30 | mocking frameworks. See the `mock documentation`_ for full details. |
| 31 | |
| 32 | Mock objects create all attributes and methods as you access them and store |
| 33 | details of how they have been used. You can configure them, to specify return |
| 34 | values or limit what attributes are available, and then make assertions about |
| 35 | how 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 |
| 45 | raise 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 | |
| 63 | Mock has many other ways you can configure it and control its behaviour. For |
| 64 | example the `spec` argument configures the mock to take its specification from |
| 65 | another object. Attempting to access attributes or methods on the mock that |
| 66 | don't exist on the spec will fail with an `AttributeError`. |
| 67 | |
| 68 | The `patch` decorator / context manager makes it easy to mock classes or |
| 69 | objects in a module under test. The object you specify will be replaced with a |
| 70 | mock (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 | |
| 96 | As well as a decorator `patch` can be used as a context manager in a with |
| 97 | statement:: |
| 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 | |
| 106 | There is also `patch.dict` for setting values in a dictionary just during the |
| 107 | scope of a test and restoring the dictionary to its original state when the |
| 108 | test 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 | |
| 117 | Mock supports the mocking of Python magic methods. The easiest way of |
| 118 | using magic methods is with the `MagicMock` class. It allows you to do |
| 119 | things 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 | |
| 128 | Mock allows you to assign functions (or other Mock instances) to magic methods |
| 129 | and they will be called appropriately. The MagicMock class is just a Mock |
| 130 | variant that has all of the magic methods pre-created for you (well - all the |
| 131 | useful ones anyway). |
| 132 | |
| 133 | The following is an example of using magic methods with the ordinary Mock |
| 134 | class:: |
| 135 | |
| 136 | >>> from mock import Mock |
| 137 | >>> mock = Mock() |
| 138 | >>> mock.__str__ = Mock(return_value = 'wheeeeee') |
| 139 | >>> str(mock) |
| 140 | 'wheeeeee' |
| 141 | |
| 142 | For ensuring that the mock objects your tests use have the same api as the |
| 143 | objects they are replacing, you can use "auto-speccing". Auto-speccing can |
| 144 | be done through the `autospec` argument to patch, or the `create_autospec` |
| 145 | function. Auto-speccing creates mock objects that have the same attributes |
| 146 | and 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 | |
| 149 | This ensures that your mocks will fail in the same way as your production |
| 150 | code 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 |
| 166 | the `__init__` method, and on callable objects where it copies the signature of |
| 167 | the `__call__` method. |
| 168 | |
| 169 | The distribution contains tests and documentation. The tests require |
| 170 | `unittest2 <http://pypi.python.org/pypi/unittest2>`_ to run. |
| 171 | |
| 172 | Docs from the in-development version of `mock` can be found at |
| 173 | `mock.readthedocs.org <http://mock.readthedocs.org>`_. |