Skip to content

Commit 811db49

Browse files
committed
Merge branch 'readme'
2 parents 39a75b6 + 1bf9866 commit 811db49

File tree

2 files changed

+87
-4
lines changed

2 files changed

+87
-4
lines changed

Diff for: README.md

-4
This file was deleted.

Diff for: README.rst

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
pytest-mock
2+
===========
3+
4+
This plugin installs a fixture ``mock`` which is a thin-wrapper around the patching API
5+
provided by the excellent `mock <http://pypi.python.org/pypi/mock>`_ package,
6+
but with the benefit of not having to worry about undoing patches at the end
7+
of a test:
8+
9+
.. code-block:: python
10+
11+
12+
def test_unix_fs(mock):
13+
mock.patch('os.remove')
14+
UnixFS.rm('file')
15+
os.remove.assert_called_once_with('file')
16+
17+
18+
Usage
19+
-----
20+
21+
The ``mock`` fixture has the same API as
22+
`mock.patch <http://www.voidspace.org.uk/python/mock/patch.html#patch-decorators>`_,
23+
supporting the same arguments:
24+
25+
.. code-block:: python
26+
27+
# all valid calls
28+
mock.patch('os.remove')
29+
mock.patch.object(os, 'listdir', autospec=True)
30+
mocked = mock.patch('os.remove')
31+
32+
The supported methods are:
33+
34+
* ``mock.patch``: see http://www.voidspace.org.uk/python/mock/patch.html#patch.
35+
* ``mock.patch.object``: see `http://www.voidspace.org.uk/python/mock/patch.html#patch-object.
36+
* ``mock.patch.multiple``: see `http://www.voidspace.org.uk/python/mock/patch.html#patch-multiple.
37+
* ``mock.stopall()``: stops all active patches at this point.
38+
39+
Why bother with a plugin?
40+
-------------------------
41+
42+
There are a number of different ``patch`` usages in the standard ``mock`` API,
43+
but IMHO they don't scale very well when you have a more than one or two
44+
patches to apply.
45+
46+
It may lead to an excessive nesting of ``with`` statements, breaking the flow
47+
of the test:
48+
49+
.. code-block:: python
50+
51+
import mock
52+
53+
def test_unix_fs():
54+
with mock.patch('os.remove'):
55+
UnixFS.rm('file')
56+
os.remote.assert_called_once_with('file')
57+
58+
with mock.patch('os.listdir'):
59+
assert UnixFS.ls('dir') == expected
60+
# ...
61+
62+
with mock.patch('shutil.copy'):
63+
UnixFS.cp('src', 'dst')
64+
# ...
65+
66+
67+
One can use ``patch`` as a decorator to improve the flow of the test, but now the
68+
test functions must receive the mock objects:
69+
70+
.. code-block:: python
71+
72+
@mock.patch('os.remove')
73+
@mock.patch('os.listdir')
74+
@mock.patch('shutil.copy')
75+
def test_unix_fs(mocked_copy, mocked_listdir, mocked_copy):
76+
UnixFS.rm('file')
77+
os.remote.assert_called_once_with('file')
78+
79+
assert UnixFS.ls('dir') == expected
80+
# ...
81+
82+
UnixFS.cp('src', 'dst')
83+
# ...
84+
85+
Even when you prefer to access the mocks using the original references. Besides
86+
don't mixing nicely with other fixtures (although it works), you can't
87+
easily undo the mocking if you follow this approach.

0 commit comments

Comments
 (0)