Skip to content

Commit

Permalink
mocker.resetall now also resets mockers created by create_autospec (#…
Browse files Browse the repository at this point in the history
…390)

Fixes #389
  • Loading branch information
inikolaev authored Oct 19, 2023
1 parent e84f885 commit 2a71a0d
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Releases
========

3.12.0 (2023-10-19)
-------------------

* ``mocker.resetall()`` now also resets mocks created by ``mocker.create_autospec`` (`#390`_).

.. _#390: https://github.com/pytest-dev/pytest-mock/pull/390

3.11.1 (2023-06-15)
-------------------

Expand Down
13 changes: 11 additions & 2 deletions src/pytest_mock/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,20 @@ def __init__(self, config: Any) -> None:
self.call = mock_module.call
self.ANY = mock_module.ANY
self.DEFAULT = mock_module.DEFAULT
self.create_autospec = mock_module.create_autospec
self.sentinel = mock_module.sentinel
self.mock_open = mock_module.mock_open
if hasattr(mock_module, "seal"):
self.seal = mock_module.seal

def create_autospec(
self, spec: Any, spec_set: bool = False, instance: bool = False, **kwargs: Any
) -> MockType:
m: MockType = self.mock_module.create_autospec(
spec, spec_set, instance, **kwargs
)
self._patches_and_mocks.append((None, m))
return m

def resetall(
self, *, return_value: bool = False, side_effect: bool = False
) -> None:
Expand Down Expand Up @@ -102,7 +110,8 @@ def stopall(self) -> None:
times.
"""
for p, m in reversed(self._patches_and_mocks):
p.stop()
if p is not None:
p.stop()
self._patches_and_mocks.clear()

def stop(self, mock: unittest.mock.MagicMock) -> None:
Expand Down
22 changes: 21 additions & 1 deletion tests/test_pytest_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ def ls(cls, path):
return os.listdir(path)


class TestObject:
"""
Class that is used for testing create_autospec with child mocks
"""

def run(self) -> str:
return "not mocked"


@pytest.fixture
def check_unix_fs_mocked(
tmpdir: Any, mocker: MockerFixture
Expand Down Expand Up @@ -156,7 +165,6 @@ def test_mock_patch_dict_resetall(mocker: MockerFixture) -> None:
[
"ANY",
"call",
"create_autospec",
"MagicMock",
"Mock",
"mock_open",
Expand Down Expand Up @@ -185,23 +193,35 @@ def test_mocker_resetall(mocker: MockerFixture) -> None:
listdir = mocker.patch("os.listdir", return_value="foo")
open = mocker.patch("os.open", side_effect=["bar", "baz"])

mocked_object = mocker.create_autospec(TestObject)
mocked_object.run.return_value = "mocked"

assert listdir("/tmp") == "foo"
assert open("/tmp/foo.txt") == "bar"
assert mocked_object.run() == "mocked"
listdir.assert_called_once_with("/tmp")
open.assert_called_once_with("/tmp/foo.txt")
mocked_object.run.assert_called_once()

mocker.resetall()

assert not listdir.called
assert not open.called
assert not mocked_object.called
assert listdir.return_value == "foo"
assert list(open.side_effect) == ["baz"]
assert mocked_object.run.return_value == "mocked"

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

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

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


class TestMockerStub:
def test_call(self, mocker: MockerFixture) -> None:
Expand Down

0 comments on commit 2a71a0d

Please sign in to comment.