michael@0: ==================================== michael@0: Mock - Mocking and Testing Library michael@0: ==================================== michael@0: michael@0: .. currentmodule:: mock michael@0: michael@0: :Author: `Michael Foord michael@0: `_ michael@0: :Version: |release| michael@0: :Date: 2012/10/07 michael@0: :Homepage: `Mock Homepage`_ michael@0: :Download: `Mock on PyPI`_ michael@0: :Documentation: `PDF Documentation michael@0: `_ michael@0: :License: `BSD License`_ michael@0: :Support: `Mailing list (testing-in-python@lists.idyll.org) michael@0: `_ michael@0: :Issue tracker: `Google code project michael@0: `_ michael@0: michael@0: .. _Mock Homepage: http://www.voidspace.org.uk/python/mock/ michael@0: .. _BSD License: http://www.voidspace.org.uk/python/license.shtml michael@0: michael@0: michael@0: .. currentmodule:: mock michael@0: michael@0: .. module:: mock michael@0: :synopsis: Mock object and testing library. michael@0: michael@0: .. index:: introduction michael@0: michael@0: mock is a library for testing in Python. It allows you to replace parts of michael@0: your system under test with mock objects and make assertions about how they michael@0: have been used. michael@0: michael@0: mock is now part of the Python standard library, available as `unittest.mock michael@0: `_ michael@0: in Python 3.3 onwards. michael@0: michael@0: mock provides a core :class:`Mock` class removing the need to create a host michael@0: of stubs throughout your test suite. After performing an action, you can make michael@0: assertions about which methods / attributes were used and arguments they were michael@0: called with. You can also specify return values and set needed attributes in michael@0: the normal way. michael@0: michael@0: Additionally, mock provides a :func:`patch` decorator that handles patching michael@0: module and class level attributes within the scope of a test, along with michael@0: :const:`sentinel` for creating unique objects. See the `quick guide`_ for michael@0: some examples of how to use :class:`Mock`, :class:`MagicMock` and michael@0: :func:`patch`. michael@0: michael@0: Mock is very easy to use and is designed for use with michael@0: `unittest `_. Mock is based on michael@0: the 'action -> assertion' pattern instead of `'record -> replay'` used by many michael@0: mocking frameworks. michael@0: michael@0: mock is tested on Python versions 2.4-2.7, Python 3 plus the latest versions of michael@0: Jython and PyPy. michael@0: michael@0: michael@0: .. testsetup:: michael@0: michael@0: class ProductionClass(object): michael@0: def method(self, *args): michael@0: pass michael@0: michael@0: module = sys.modules['module'] = ProductionClass michael@0: ProductionClass.ClassName1 = ProductionClass michael@0: ProductionClass.ClassName2 = ProductionClass michael@0: michael@0: michael@0: michael@0: API Documentation michael@0: ================= michael@0: michael@0: .. toctree:: michael@0: :maxdepth: 2 michael@0: michael@0: mock michael@0: patch michael@0: helpers michael@0: sentinel michael@0: magicmock michael@0: michael@0: michael@0: User Guide michael@0: ========== michael@0: michael@0: .. toctree:: michael@0: :maxdepth: 2 michael@0: michael@0: getting-started michael@0: examples michael@0: compare michael@0: changelog michael@0: michael@0: michael@0: .. index:: installing michael@0: michael@0: Installing michael@0: ========== michael@0: michael@0: The current version is |release|. Mock is stable and widely used. If you do michael@0: find any bugs, or have suggestions for improvements / extensions michael@0: then please contact us. michael@0: michael@0: * `mock on PyPI `_ michael@0: * `mock documentation as PDF michael@0: `_ michael@0: * `Google Code Home & Mercurial Repository `_ michael@0: michael@0: .. index:: repository michael@0: .. index:: hg michael@0: michael@0: You can checkout the latest development version from the Google Code Mercurial michael@0: repository with the following command: michael@0: michael@0: ``hg clone https://mock.googlecode.com/hg/ mock`` michael@0: michael@0: michael@0: .. index:: pip michael@0: .. index:: easy_install michael@0: .. index:: setuptools michael@0: michael@0: If you have pip, setuptools or distribute you can install mock with: michael@0: michael@0: | ``easy_install -U mock`` michael@0: | ``pip install -U mock`` michael@0: michael@0: Alternatively you can download the mock distribution from PyPI and after michael@0: unpacking run: michael@0: michael@0: ``python setup.py install`` michael@0: michael@0: michael@0: Quick Guide michael@0: =========== michael@0: michael@0: :class:`Mock` and :class:`MagicMock` objects create all attributes and michael@0: methods as you access them and store details of how they have been used. You michael@0: can configure them, to specify return values or limit what attributes are michael@0: available, and then make assertions about how they have been used: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> from mock import MagicMock michael@0: >>> thing = ProductionClass() michael@0: >>> thing.method = MagicMock(return_value=3) michael@0: >>> thing.method(3, 4, 5, key='value') michael@0: 3 michael@0: >>> thing.method.assert_called_with(3, 4, 5, key='value') michael@0: michael@0: :attr:`side_effect` allows you to perform side effects, including raising an michael@0: exception when a mock is called: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> mock = Mock(side_effect=KeyError('foo')) michael@0: >>> mock() michael@0: Traceback (most recent call last): michael@0: ... michael@0: KeyError: 'foo' michael@0: michael@0: >>> values = {'a': 1, 'b': 2, 'c': 3} michael@0: >>> def side_effect(arg): michael@0: ... return values[arg] michael@0: ... michael@0: >>> mock.side_effect = side_effect michael@0: >>> mock('a'), mock('b'), mock('c') michael@0: (1, 2, 3) michael@0: >>> mock.side_effect = [5, 4, 3, 2, 1] michael@0: >>> mock(), mock(), mock() michael@0: (5, 4, 3) michael@0: michael@0: Mock has many other ways you can configure it and control its behaviour. For michael@0: example the `spec` argument configures the mock to take its specification michael@0: from another object. Attempting to access attributes or methods on the mock michael@0: that don't exist on the spec will fail with an `AttributeError`. michael@0: michael@0: The :func:`patch` decorator / context manager makes it easy to mock classes or michael@0: objects in a module under test. The object you specify will be replaced with a michael@0: mock (or other object) during the test and restored when the test ends: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> from mock import patch michael@0: >>> @patch('module.ClassName2') michael@0: ... @patch('module.ClassName1') michael@0: ... def test(MockClass1, MockClass2): michael@0: ... module.ClassName1() michael@0: ... module.ClassName2() michael@0: michael@0: ... assert MockClass1 is module.ClassName1 michael@0: ... assert MockClass2 is module.ClassName2 michael@0: ... assert MockClass1.called michael@0: ... assert MockClass2.called michael@0: ... michael@0: >>> test() michael@0: michael@0: .. note:: michael@0: michael@0: When you nest patch decorators the mocks are passed in to the decorated michael@0: function in the same order they applied (the normal *python* order that michael@0: decorators are applied). This means from the bottom up, so in the example michael@0: above the mock for `module.ClassName1` is passed in first. michael@0: michael@0: With `patch` it matters that you patch objects in the namespace where they michael@0: are looked up. This is normally straightforward, but for a quick guide michael@0: read :ref:`where to patch `. michael@0: michael@0: As well as a decorator `patch` can be used as a context manager in a with michael@0: statement: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> with patch.object(ProductionClass, 'method', return_value=None) as mock_method: michael@0: ... thing = ProductionClass() michael@0: ... thing.method(1, 2, 3) michael@0: ... michael@0: >>> mock_method.assert_called_once_with(1, 2, 3) michael@0: michael@0: michael@0: There is also :func:`patch.dict` for setting values in a dictionary just michael@0: during a scope and restoring the dictionary to its original state when the test michael@0: ends: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> foo = {'key': 'value'} michael@0: >>> original = foo.copy() michael@0: >>> with patch.dict(foo, {'newkey': 'newvalue'}, clear=True): michael@0: ... assert foo == {'newkey': 'newvalue'} michael@0: ... michael@0: >>> assert foo == original michael@0: michael@0: Mock supports the mocking of Python :ref:`magic methods `. The michael@0: easiest way of using magic methods is with the :class:`MagicMock` class. It michael@0: allows you to do things like: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> mock = MagicMock() michael@0: >>> mock.__str__.return_value = 'foobarbaz' michael@0: >>> str(mock) michael@0: 'foobarbaz' michael@0: >>> mock.__str__.assert_called_with() michael@0: michael@0: Mock allows you to assign functions (or other Mock instances) to magic methods michael@0: and they will be called appropriately. The `MagicMock` class is just a Mock michael@0: variant that has all of the magic methods pre-created for you (well, all the michael@0: useful ones anyway). michael@0: michael@0: The following is an example of using magic methods with the ordinary Mock michael@0: class: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> mock = Mock() michael@0: >>> mock.__str__ = Mock(return_value='wheeeeee') michael@0: >>> str(mock) michael@0: 'wheeeeee' michael@0: michael@0: For ensuring that the mock objects in your tests have the same api as the michael@0: objects they are replacing, you can use :ref:`auto-speccing `. michael@0: Auto-speccing can be done through the `autospec` argument to patch, or the michael@0: :func:`create_autospec` function. Auto-speccing creates mock objects that michael@0: have the same attributes and methods as the objects they are replacing, and michael@0: any functions and methods (including constructors) have the same call michael@0: signature as the real object. michael@0: michael@0: This ensures that your mocks will fail in the same way as your production michael@0: code if they are used incorrectly: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> from mock import create_autospec michael@0: >>> def function(a, b, c): michael@0: ... pass michael@0: ... michael@0: >>> mock_function = create_autospec(function, return_value='fishy') michael@0: >>> mock_function(1, 2, 3) michael@0: 'fishy' michael@0: >>> mock_function.assert_called_once_with(1, 2, 3) michael@0: >>> mock_function('wrong arguments') michael@0: Traceback (most recent call last): michael@0: ... michael@0: TypeError: () takes exactly 3 arguments (1 given) michael@0: michael@0: `create_autospec` can also be used on classes, where it copies the signature of michael@0: the `__init__` method, and on callable objects where it copies the signature of michael@0: the `__call__` method. michael@0: michael@0: michael@0: .. index:: references michael@0: .. index:: articles michael@0: michael@0: References michael@0: ========== michael@0: michael@0: Articles, blog entries and other stuff related to testing with Mock: michael@0: michael@0: * `Imposing a No DB Discipline on Django unit tests michael@0: `_ michael@0: * `mock-django: tools for mocking the Django ORM and models michael@0: `_ michael@0: * `PyCon 2011 Video: Testing with mock `_ michael@0: * `Mock objects in Python michael@0: `_ michael@0: * `Python: Injecting Mock Objects for Powerful Testing michael@0: `_ michael@0: * `Python Mock: How to assert a substring of logger output michael@0: `_ michael@0: * `Mocking Django `_ michael@0: * `Mocking dates and other classes that can't be modified michael@0: `_ michael@0: * `Mock recipes `_ michael@0: * `Mockity mock mock - some love for the mock module michael@0: `_ michael@0: * `Coverage and Mock (with django) michael@0: `_ michael@0: * `Python Unit Testing with Mock `_ michael@0: * `Getting started with Python Mock michael@0: `_ michael@0: * `Smart Parameter Checks with mock michael@0: `_ michael@0: * `Python mock testing techniques and tools michael@0: `_ michael@0: * `How To Test Django Template Tags michael@0: `_ michael@0: * `A presentation on Unit Testing with Mock michael@0: `_ michael@0: * `Mocking with Django and Google AppEngine michael@0: `_ michael@0: michael@0: michael@0: .. index:: tests michael@0: .. index:: unittest2 michael@0: michael@0: Tests michael@0: ===== michael@0: michael@0: Mock uses `unittest2 `_ for its own michael@0: test suite. In order to run it, use the `unit2` script that comes with michael@0: `unittest2` module on a checkout of the source repository: michael@0: michael@0: `unit2 discover` michael@0: michael@0: If you have `setuptools `_ as well as michael@0: unittest2 you can run: michael@0: michael@0: ``python setup.py test`` michael@0: michael@0: On Python 3.2 you can use ``unittest`` module from the standard library. michael@0: michael@0: ``python3.2 -m unittest discover`` michael@0: michael@0: .. index:: Python 3 michael@0: michael@0: On Python 3 the tests for unicode are skipped as they are not relevant. On michael@0: Python 2.4 tests that use the with statements are skipped as the with statement michael@0: is invalid syntax on Python 2.4. michael@0: michael@0: michael@0: .. index:: older versions michael@0: michael@0: Older Versions michael@0: ============== michael@0: michael@0: Documentation for older versions of mock: michael@0: michael@0: * `mock 0.8 `_ michael@0: * `mock 0.7 `_ michael@0: * `mock 0.6 `_ michael@0: michael@0: Docs from the in-development version of `mock` can be found at michael@0: `mock.readthedocs.org `_. michael@0: michael@0: michael@0: Terminology michael@0: =========== michael@0: michael@0: Terminology for objects used to replace other ones can be confusing. Terms michael@0: like double, fake, mock, stub, and spy are all used with varying meanings. michael@0: michael@0: In `classic mock terminology michael@0: `_ michael@0: :class:`mock.Mock` is a `spy `_ that michael@0: allows for *post-mortem* examination. This is what I call the "action -> michael@0: assertion" [#]_ pattern of testing. michael@0: michael@0: I'm not however a fan of this "statically typed mocking terminology" michael@0: promulgated by `Martin Fowler michael@0: `_. It confuses usage michael@0: patterns with implementation and prevents you from using natural terminology michael@0: when discussing mocking. michael@0: michael@0: I much prefer duck typing, if an object used in your test suite looks like a michael@0: mock object and quacks like a mock object then it's fine to call it a mock, no michael@0: matter what the implementation looks like. michael@0: michael@0: This terminology is perhaps more useful in less capable languages where michael@0: different usage patterns will *require* different implementations. michael@0: `mock.Mock()` is capable of being used in most of the different roles michael@0: described by Fowler, except (annoyingly / frustratingly / ironically) a Mock michael@0: itself! michael@0: michael@0: How about a simpler definition: a "mock object" is an object used to replace a michael@0: real one in a system under test. michael@0: michael@0: .. [#] This pattern is called "AAA" by some members of the testing community; michael@0: "Arrange - Act - Assert".