Skip to content

Commit 2a71a0d

Browse files
authored
mocker.resetall now also resets mockers created by create_autospec (#390)
Fixes #389
1 parent e84f885 commit 2a71a0d

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

CHANGELOG.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
Releases
22
========
33

4+
3.12.0 (2023-10-19)
5+
-------------------
6+
7+
* ``mocker.resetall()`` now also resets mocks created by ``mocker.create_autospec`` (`#390`_).
8+
9+
.. _#390: https://github.com/pytest-dev/pytest-mock/pull/390
10+
411
3.11.1 (2023-06-15)
512
-------------------
613

src/pytest_mock/plugin.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,20 @@ def __init__(self, config: Any) -> None:
6666
self.call = mock_module.call
6767
self.ANY = mock_module.ANY
6868
self.DEFAULT = mock_module.DEFAULT
69-
self.create_autospec = mock_module.create_autospec
7069
self.sentinel = mock_module.sentinel
7170
self.mock_open = mock_module.mock_open
7271
if hasattr(mock_module, "seal"):
7372
self.seal = mock_module.seal
7473

74+
def create_autospec(
75+
self, spec: Any, spec_set: bool = False, instance: bool = False, **kwargs: Any
76+
) -> MockType:
77+
m: MockType = self.mock_module.create_autospec(
78+
spec, spec_set, instance, **kwargs
79+
)
80+
self._patches_and_mocks.append((None, m))
81+
return m
82+
7583
def resetall(
7684
self, *, return_value: bool = False, side_effect: bool = False
7785
) -> None:
@@ -102,7 +110,8 @@ def stopall(self) -> None:
102110
times.
103111
"""
104112
for p, m in reversed(self._patches_and_mocks):
105-
p.stop()
113+
if p is not None:
114+
p.stop()
106115
self._patches_and_mocks.clear()
107116

108117
def stop(self, mock: unittest.mock.MagicMock) -> None:

tests/test_pytest_mock.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,15 @@ def ls(cls, path):
6060
return os.listdir(path)
6161

6262

63+
class TestObject:
64+
"""
65+
Class that is used for testing create_autospec with child mocks
66+
"""
67+
68+
def run(self) -> str:
69+
return "not mocked"
70+
71+
6372
@pytest.fixture
6473
def check_unix_fs_mocked(
6574
tmpdir: Any, mocker: MockerFixture
@@ -156,7 +165,6 @@ def test_mock_patch_dict_resetall(mocker: MockerFixture) -> None:
156165
[
157166
"ANY",
158167
"call",
159-
"create_autospec",
160168
"MagicMock",
161169
"Mock",
162170
"mock_open",
@@ -185,23 +193,35 @@ def test_mocker_resetall(mocker: MockerFixture) -> None:
185193
listdir = mocker.patch("os.listdir", return_value="foo")
186194
open = mocker.patch("os.open", side_effect=["bar", "baz"])
187195

196+
mocked_object = mocker.create_autospec(TestObject)
197+
mocked_object.run.return_value = "mocked"
198+
188199
assert listdir("/tmp") == "foo"
189200
assert open("/tmp/foo.txt") == "bar"
201+
assert mocked_object.run() == "mocked"
190202
listdir.assert_called_once_with("/tmp")
191203
open.assert_called_once_with("/tmp/foo.txt")
204+
mocked_object.run.assert_called_once()
192205

193206
mocker.resetall()
194207

195208
assert not listdir.called
196209
assert not open.called
210+
assert not mocked_object.called
197211
assert listdir.return_value == "foo"
198212
assert list(open.side_effect) == ["baz"]
213+
assert mocked_object.run.return_value == "mocked"
199214

200215
mocker.resetall(return_value=True, side_effect=True)
201216

202217
assert isinstance(listdir.return_value, mocker.Mock)
203218
assert open.side_effect is None
204219

220+
if sys.version_info >= (3, 9):
221+
# The reset on child mocks have been implemented in 3.9
222+
# https://bugs.python.org/issue38932
223+
assert mocked_object.run.return_value != "mocked"
224+
205225

206226
class TestMockerStub:
207227
def test_call(self, mocker: MockerFixture) -> None:

0 commit comments

Comments
 (0)