Skip to content
Snippets Groups Projects
Commit 5b60b419 authored by Michael Foord's avatar Michael Foord
Browse files

Documentation update and failing test for create_autospec

parent db9abf92
No related branches found
No related tags found
No related merge requests found
mock is a Python module that provides a core Mock class. It removes the need mock is a library for testing in Python. It allows you to replace parts of
to create a host of stubs throughout your test suite. After performing an your system under test with mock objects and make assertions about how they
action, you can make assertions about which methods / attributes were used and have been used.
arguments they were called with. You can also specify return values and set
needed attributes in the normal way. mock provides a core 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.
mock is tested on Python versions 2.4-2.7 and Python 3. mock is also tested mock is tested on Python versions 2.4-2.7 and Python 3. mock is also tested
with the latest versions of Jython and pypy. with the latest versions of Jython and pypy.
...@@ -37,29 +41,31 @@ how they have been used:: ...@@ -37,29 +41,31 @@ how they have been used::
3 3
>>> real.method.assert_called_with(3, 4, 5, key='value') >>> real.method.assert_called_with(3, 4, 5, key='value')
``side_effect`` allows you to perform side effects, return different values or `side_effect` allows you to perform side effects, return different values or
raise an exception when a mock is called:: raise an exception when a mock is called::
>>> from mock import Mock
>>> mock = Mock(side_effect=KeyError('foo')) >>> mock = Mock(side_effect=KeyError('foo'))
>>> mock() >>> mock()
Traceback (most recent call last): Traceback (most recent call last):
... ...
KeyError: 'foo' KeyError: 'foo'
>>> values = [1, 2, 3] >>> values = {'a': 1, 'b': 2, 'c': 3}
>>> def side_effect(): >>> def side_effect(arg):
... return values.pop() ... return values[arg]
... ...
>>> mock.side_effect = side_effect >>> mock.side_effect = side_effect
>>> mock(), mock(), mock() >>> mock('a'), mock('b'), mock('c')
(3, 2, 1) (3, 2, 1)
>>> 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 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 example the `spec` argument configures the mock to take its specification from
another object. Attempting to access attributes or methods on the mock that another object. Attempting to access attributes or methods on the mock that
don't exist on the spec will fail with an ``AttributeError``. don't exist on the spec will fail with an `AttributeError`.
The ``patch`` decorator / context manager makes it easy to mock classes or The `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 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:: mock (or other object) during the test and restored when the test ends::
...@@ -109,7 +115,7 @@ test ends:: ...@@ -109,7 +115,7 @@ test ends::
>>> assert foo == original >>> assert foo == original
Mock now supports the mocking of Python magic methods. The easiest way of Mock now supports the mocking of Python magic methods. The easiest way of
using magic methods is with the ``MagicMock`` class. It allows you to do using magic methods is with the `MagicMock` class. It allows you to do
things like:: things like::
>>> from mock import MagicMock >>> from mock import MagicMock
...@@ -134,26 +140,30 @@ class:: ...@@ -134,26 +140,30 @@ class::
>>> str(mock) >>> str(mock)
'wheeeeee' 'wheeeeee'
`mocksignature` is a useful companion to Mock and patch. It creates For ensuring that the mock objects your tests use have the same api as the
copies of functions that delegate to a mock, but have the same signature as the objects they are replacing, you can use "auto-speccing". Auto-speccing can
original function. This ensures that your mocks will fail in the same way as be done through the `autospec` argument to patch, or the `create_autospec`
your production code if they are called incorrectly:: 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::
>>> from mock import mocksignature >>> from mock import create_autospec
>>> def function(a, b, c): >>> def function(a, b, c):
... pass ... pass
... ...
>>> function2 = mocksignature(function) >>> mock_function = create_autospec(function, return_value='fishy')
>>> function2.mock.return_value = 'fishy' >>> mock_function(1, 2, 3)
>>> function2(1, 2, 3)
'fishy' 'fishy'
>>> function2.mock.assert_called_with(1, 2, 3) >>> mock_function.assert_called_once_with(1, 2, 3)
>>> function2('wrong arguments') >>> mock_function('wrong arguments')
Traceback (most recent call last): Traceback (most recent call last):
... ...
TypeError: <lambda>() takes exactly 3 arguments (1 given) TypeError: <lambda>() takes exactly 3 arguments (1 given)
`mocksignature` can also be used on classes, where it copies the signature of `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 `__init__` method, and on callable objects where it copies the signature of
the `__call__` method. the `__call__` method.
......
...@@ -116,7 +116,7 @@ mock 0.8.0 is the last version that will support Python 2.4. ...@@ -116,7 +116,7 @@ mock 0.8.0 is the last version that will support Python 2.4.
* Improved repr for mocks * Improved repr for mocks
* Improved repr for `Mock.call_args` and entries in `Mock.call_args_list`, * Improved repr for `Mock.call_args` and entries in `Mock.call_args_list`,
`Mock.method_calls` and `Mock.mock_calls` `Mock.method_calls` and `Mock.mock_calls`
* patch lookup is done at use time not at decoration time * `patch` lookup is done at use time not at decoration time
* In Python 2.6 or more recent, `dir` on a mock will report all the dynamically * In Python 2.6 or more recent, `dir` on a mock will report all the dynamically
created attributes (or the full list of attributes if there is a spec) as created attributes (or the full list of attributes if there is a spec) as
well as all the mock methods and attributes. well as all the mock methods and attributes.
...@@ -158,10 +158,17 @@ mock 0.8.0 is the last version that will support Python 2.4. ...@@ -158,10 +158,17 @@ mock 0.8.0 is the last version that will support Python 2.4.
* Added license file to the distribution * Added license file to the distribution
2011/XX/XX Version 0.8.0 release candidate 1
--------------------------------------------
* `create_autospec` on the return value of a mock class will use `__call__`
for the signature rather than `__init__`
2011/10/09 Version 0.8.0 beta 4 2011/10/09 Version 0.8.0 beta 4
------------------------------- -------------------------------
* patch lookup is done at use time not at decoration time * `patch` lookup is done at use time not at decoration time
* When attaching a Mock to another Mock as a magic method, calls are recorded * When attaching a Mock to another Mock as a magic method, calls are recorded
in mock_calls in mock_calls
* Addition of `attach_mock` method * Addition of `attach_mock` method
......
=========
Helpers
=========
.. currentmodule:: mock
.. testsetup::
import sys, unittest2
from mock import MagicMock, Mock, patch
call
====
create_autospec
===============
ANY
===
...@@ -29,24 +29,29 @@ ...@@ -29,24 +29,29 @@
.. index:: introduction .. index:: introduction
mock is a Python module that provides a core :class:`Mock` class. It removes mock is a library for testing in Python. It allows you to replace parts of
the need to create a host of stubs throughout your test suite. After your system under test with mock objects and make assertions about how they
performing an action, you can make assertions about which methods / attributes have been used.
were used and arguments they were called with. You can also specify return
values and set needed attributes in the normal way. 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
The mock module also provides a :func:`patch` decorator that handles assertions about which methods / attributes were used and arguments they were
patching module and class level attributes within the scope of a test, along called with. You can also specify return values and set needed attributes in
with :const:`sentinel` for creating unique objects. See the `quick guide`_ for the normal way.
some examples of how to use :class:`Mock`, :class:`MagicMock` and :func:`patch`.
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 Mock is very easy to use and is designed for use with
`unittest <http://pypi.python.org/pypi/unittest2>`_. Mock is based on `unittest <http://pypi.python.org/pypi/unittest2>`_. Mock is based on
the 'action -> assertion' pattern instead of `'record -> replay'` used by many the 'action -> assertion' pattern instead of `'record -> replay'` used by many
mocking frameworks. mocking frameworks.
mock is tested on Python versions 2.4-2.7 and Python 3. mock is also tested with mock is tested on Python versions 2.4-2.7 and Python 3. mock is also tested
the latest versions of Jython and pypy. with the latest versions of Jython and pypy.
.. testsetup:: .. testsetup::
...@@ -70,6 +75,7 @@ API Documentation ...@@ -70,6 +75,7 @@ API Documentation
mock mock
patch patch
helpers
sentinel sentinel
magicmock magicmock
mocksignature mocksignature
...@@ -86,6 +92,7 @@ User Guide ...@@ -86,6 +92,7 @@ User Guide
compare compare
changelog changelog
.. index:: installing .. index:: installing
Installing Installing
...@@ -127,10 +134,10 @@ unpacking run: ...@@ -127,10 +134,10 @@ unpacking run:
Quick Guide Quick Guide
=========== ===========
:class:`Mock` objects create all attributes and methods as you access them and store :class:`Mock` and :class:`MagicMock` objects create all attributes and
details of how they have been used. You can configure them, to specify return methods as you access them and store details of how they have been used. You
values or limit what attributes are available, and then make assertions about can configure them, to specify return values or limit what attributes are
how they have been used: available, and then make assertions about how they have been used:
.. doctest:: .. doctest::
...@@ -151,13 +158,16 @@ values or raise an exception when a mock is called: ...@@ -151,13 +158,16 @@ values or raise an exception when a mock is called:
Traceback (most recent call last): Traceback (most recent call last):
... ...
KeyError: 'foo' KeyError: 'foo'
>>> values = [1, 2, 3] >>> values = {'a': 1, 'b': 2, 'c': 3}
>>> def side_effect(): >>> def side_effect(arg):
... return values.pop() ... return values[arg]
... ...
>>> mock.side_effect = side_effect >>> mock.side_effect = side_effect
>>> mock(), mock(), mock() >>> mock('a'), mock('b'), mock('c')
(3, 2, 1) (3, 2, 1)
>>> 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 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 example the ``spec`` argument configures the mock to take its specification from
......
...@@ -280,9 +280,9 @@ another one. There can be many names pointing to any individual object, so ...@@ -280,9 +280,9 @@ another one. There can be many names pointing to any individual object, so
for patching to work you must ensure that you patch the name used by the system for patching to work you must ensure that you patch the name used by the system
under test. under test.
The basic principle is that you patch where an object is *used*, which is not The basic principle is that you patch where an object is *looked up*, which
necessarily the same place as where it is defined. A couple of examples will is not necessarily the same place as where it is defined. A couple of
help to clarify this. examples will help to clarify this.
Imagine we have a project that we want to test with the following structure:: Imagine we have a project that we want to test with the following structure::
......
...@@ -646,6 +646,11 @@ class SpecSignatureTest(unittest2.TestCase): ...@@ -646,6 +646,11 @@ class SpecSignatureTest(unittest2.TestCase):
mock.assert_called_once_with() mock.assert_called_once_with()
self.assertRaises(TypeError, mock, 'a') self.assertRaises(TypeError, mock, 'a')
instance = mock()
self.assertRaises(TypeError, instance)
instance(a='a')
instance.assert_called_once_with(a='a')
mock = create_autospec(Callable()) mock = create_autospec(Callable())
mock(a='a') mock(a='a')
mock.assert_called_once_with(a='a') mock.assert_called_once_with(a='a')
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment