Skip to content

Commit 8cec1d4

Browse files
committed
Merge pull request #12 from fogo/add-spy-stub
Added methods spy and stub to mocker fixture
2 parents 9c8c3d4 + 8882e98 commit 8cec1d4

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

README.rst

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,46 @@ fixture:
6969
ret = [mocker.Mock(return_value=True), mocker.Mock(return_value=True)]
7070
mocker.patch('mylib.func', side_effect=ret)
7171
72+
*New in version 0.5*
73+
74+
Spy
75+
---
76+
77+
*New in version 0.6*
78+
79+
The spy acts exactly like the original method in all cases, except it allows use of `mock`
80+
features with it, like retrieving call count.
81+
82+
.. code-block:: python
83+
84+
def test_spy(mocker):
85+
class Foo(object):
86+
def bar(self):
87+
return 42
88+
89+
foo = Foo()
90+
mocker.spy(foo, 'bar')
91+
assert foo.bar() == 42
92+
assert foo.bar.call_count == 1
93+
94+
Stub
95+
----
96+
97+
*New in version 0.6*
98+
99+
The stub is a mock object that accepts any arguments and is useful to test callbacks, for instance.
100+
101+
.. code-block:: python
102+
103+
def test_stub(mocker):
104+
def foo(on_something):
105+
on_something('foo', 'bar')
106+
107+
stub = mocker.stub()
108+
109+
foo(stub)
110+
stub.assert_called_once_with('foo', 'bar')
111+
72112
Note
73113
----
74114

pytest_mock.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,31 @@ def stopall(self):
3131
p.stop()
3232
self._patches[:] = []
3333

34+
def spy(self, obj, method_name):
35+
"""
36+
Creates a spy of method. It will run method normally, but it is now possible to use `mock`
37+
call features with it, like call count.
38+
39+
:param object obj:
40+
An object.
41+
42+
:param unicode method_name:
43+
A method in object.
44+
45+
:return: mock.MagicMock
46+
Spy object.
47+
"""
48+
return self.patch.object(obj, method_name, side_effect=getattr(obj, method_name))
49+
50+
def stub(self):
51+
"""
52+
Creates a stub method. It accepts any arguments. Ideal to register to callbacks in tests.
53+
54+
:return: mock.MagicMock
55+
Stub object.
56+
"""
57+
return mock_module.MagicMock(spec=lambda *args, **kwargs: None)
58+
3459
class _Patcher(object):
3560
"""
3661
Object to provide the same interface as mock.patch, mock.patch.object,

test_pytest_mock.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,26 @@ def test_mocker_has_mock_class_as_attribute_for_instantiation():
136136

137137
mocker = MockFixture()
138138
assert isinstance(mocker.Mock(), mock_module.Mock)
139+
140+
141+
def test_mocker_spy(mocker):
142+
class Foo(object):
143+
144+
def bar(self, arg):
145+
return arg * 2
146+
147+
foo = Foo()
148+
spy = mocker.spy(foo, 'bar')
149+
150+
assert foo.bar(arg=10) == 20
151+
spy.assert_called_once_with(arg=10)
152+
153+
154+
def test_mocker_stub(mocker):
155+
def foo(on_something):
156+
on_something('foo', 'bar')
157+
158+
stub = mocker.stub()
159+
160+
foo(stub)
161+
stub.assert_called_once_with('foo', 'bar')

0 commit comments

Comments
 (0)