diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 46d1677..843023c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,7 @@ Releases Unreleased ---------- +* `#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 `_: Added ``SpyType`` for annotating ``mocker.spy`` results. * Dropped support for EOL Python 3.9. * `#147 `_: Removed handling of ``RuntimeError: stop called on unstarted patcher``, which can no longer occur in the supported Python versions. diff --git a/src/pytest_mock/plugin.py b/src/pytest_mock/plugin.py index df63fb4..4ba8757 100644 --- a/src/pytest_mock/plugin.py +++ b/src/pytest_mock/plugin.py @@ -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"): @@ -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 ) diff --git a/tests/test_pytest_mock.py b/tests/test_pytest_mock.py index c497aea..50b6a57 100644 --- a/tests/test_pytest_mock.py +++ b/tests/test_pytest_mock.py @@ -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()