Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Releases
Unreleased
----------

* `#606 <https://github.com/pytest-dev/pytest-mock/pull/606>`_: ``mocker.resetall(return_value=True, side_effect=True)`` now also applies to non-callable mocks, such as those returned by ``mocker.create_autospec(SomeClass, instance=True)``. Previously both arguments were silently ignored for them.
* `#547 <https://github.com/pytest-dev/pytest-mock/issues/547>`_: Added ``SpyType`` for annotating ``mocker.spy`` results.
* Dropped support for EOL Python 3.9.
* `#147 <https://github.com/pytest-dev/pytest-mock/issues/147>`_: Removed handling of ``RuntimeError: stop called on unstarted patcher``, which can no longer occur in the supported Python versions.
Expand Down
12 changes: 5 additions & 7 deletions src/pytest_mock/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,6 @@ def resetall(
:param bool return_value: Reset the return_value of mocks.
:param bool side_effect: Reset the side_effect of mocks.
"""
supports_reset_mock_with_args: tuple[type[Any], ...]
if hasattr(self, "AsyncMock"):
supports_reset_mock_with_args = (self.Mock, self.AsyncMock)
else:
supports_reset_mock_with_args = (self.Mock,)

for mock_item in self._mock_cache:
# See issue #237.
if not hasattr(mock_item.mock, "reset_mock"):
Expand All @@ -145,7 +139,11 @@ def resetall(
mock_item.mock.spy_return_list = []
if hasattr(mock_item.mock, "spy_return_iter"):
mock_item.mock.spy_return_iter = None
if isinstance(mock_item.mock, supports_reset_mock_with_args):
# ``reset_mock`` is defined on ``NonCallableMock``, which is the base
# of every mock class. Autospecced *functions* are plain functions
# carrying a no-argument ``reset_mock`` closure, so they take the
# ``else`` branch.
if isinstance(mock_item.mock, self.NonCallableMock):
mock_item.mock.reset_mock(
return_value=return_value, side_effect=side_effect
)
Expand Down
13 changes: 13 additions & 0 deletions tests/test_pytest_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,19 @@ def test_mocker_resetall(mocker: MockerFixture) -> None:
assert mocked_object.run.return_value != "mocked"


def test_mocker_resetall_non_callable_mock(mocker: MockerFixture) -> None:
"""``resetall`` must honour its arguments for non-callable mocks too (#389)."""
mocked_object = mocker.create_autospec(TestObject, instance=True)
assert not isinstance(mocked_object, mocker.Mock)
mocked_object.run.return_value = "mocked"
mocked_object.run.side_effect = ValueError

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

assert mocked_object.run.return_value != "mocked"
assert mocked_object.run.side_effect is None


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