michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: Mock - Mocking and Testing Library — Mock 1.0.0 documentation michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0:
michael@0:
michael@0:
michael@0:
michael@0: michael@0:
michael@0:

Mock - Mocking and Testing Library

michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0:
Author:Michael Foord
Version:1.0.0
Date:2012/10/07
Homepage:Mock Homepage
Download:Mock on PyPI
Documentation:PDF Documentation
License:BSD License
Support:Mailing list (testing-in-python@lists.idyll.org)
Issue tracker:Google code project
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:

mock is now part of the Python standard library, available as unittest.mock michael@0: in Python 3.3 onwards.

michael@0:

mock provides a core 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:

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

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:

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:

API Documentation

michael@0:
michael@0: michael@0:
michael@0:
michael@0:
michael@0:

User Guide

michael@0:
michael@0: michael@0:
michael@0:
michael@0:
michael@0:

Installing

michael@0:

The current version is 1.0.0. 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:

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:

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

michael@0:
michael@0:
michael@0:
easy_install -U mock
michael@0:
pip install -U mock
michael@0:
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:

Mock and 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:
>>> 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:
michael@0:

side_effect allows you to perform side effects, including raising an michael@0: exception when a mock is called:

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:
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:

The 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:
>>> 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:
michael@0:
michael@0:

Note

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:

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 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:
>>> 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 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:
>>> 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:
michael@0:

Mock supports the mocking of Python magic methods. The michael@0: easiest way of using magic methods is with the MagicMock class. It michael@0: allows you to do things like:

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:
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:

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

michael@0:
>>> mock = Mock()
michael@0: >>> mock.__str__ = Mock(return_value='wheeeeee')
michael@0: >>> str(mock)
michael@0: 'wheeeeee'
michael@0: 
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 auto-speccing. michael@0: Auto-speccing can be done through the autospec argument to patch, or the michael@0: 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:

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

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: <lambda>() takes exactly 3 arguments (1 given)
michael@0: 
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:
michael@0:

Tests

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:

If you have setuptools as well as michael@0: unittest2 you can run:

michael@0:
michael@0:
python setup.py test
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:

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:

Older Versions

michael@0:

Documentation for older versions of mock:

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:

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:

In classic mock terminology michael@0: mock.Mock is a spy that michael@0: allows for post-mortem examination. This is what I call the “action -> michael@0: assertion” [1] pattern of testing.

michael@0:

I’m not however a fan of this “statically typed mocking terminology” michael@0: promulgated by Martin Fowler. It confuses usage michael@0: patterns with implementation and prevents you from using natural terminology michael@0: when discussing mocking.

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:

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:

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: michael@0: michael@0: michael@0: michael@0:
[1]This pattern is called “AAA” by some members of the testing community; michael@0: “Arrange - Act - Assert”.
michael@0:
michael@0:
michael@0: michael@0: michael@0:
michael@0:
michael@0:
michael@0:
michael@0:
michael@0:

Table Of Contents

michael@0: michael@0: michael@0:

Next topic

michael@0:

The Mock Class

michael@0:

This Page

michael@0: michael@0: michael@0: michael@0:
michael@0:
michael@0:
michael@0:
michael@0: michael@0: michael@0: michael@0: