diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d40165b..ab7cf60 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,9 @@ +1.13.0 (2019-12-05) +------------------- + +* The object returned by ``mocker.spy`` now also tracks any side effect + of the spied method/function. + 1.12.1 (2019-11-20) ------------------- diff --git a/README.rst b/README.rst index ed7e886..bd1ccc2 100644 --- a/README.rst +++ b/README.rst @@ -103,6 +103,9 @@ features with it, like retrieving call count. It also works for class and static Since version ``1.11``, it is also possible to query the ``return_value`` attribute to observe what the spied function/method returned. +Since version ``1.13``, it is also possible to query the ``side_effect`` attribute +to observe any exception thrown by the spied function/method. + Stub ---- diff --git a/src/pytest_mock/plugin.py b/src/pytest_mock/plugin.py index dda073a..470072b 100644 --- a/src/pytest_mock/plugin.py +++ b/src/pytest_mock/plugin.py @@ -113,8 +113,13 @@ def spy(self, obj, name): @w def wrapper(*args, **kwargs): - r = method(*args, **kwargs) - result.return_value = r + try: + r = method(*args, **kwargs) + except Exception as e: + result.side_effect = e + raise + else: + result.return_value = r return r result = self.patch.object(obj, name, side_effect=wrapper, autospec=autospec) diff --git a/tests/test_pytest_mock.py b/tests/test_pytest_mock.py index dd8c3a9..04261f5 100644 --- a/tests/test_pytest_mock.py +++ b/tests/test_pytest_mock.py @@ -243,6 +243,25 @@ def bar(self, arg): assert spy.return_value == 20 +def test_instance_method_spy_exception(mocker): + excepted_message = "foo" + + class Foo(object): + def bar(self, arg): + raise Exception(excepted_message) + + foo = Foo() + other = Foo() + spy = mocker.spy(foo, "bar") + + with pytest.raises(Exception) as exc_info: + foo.bar(10) + assert str(exc_info.value) == excepted_message + + foo.bar.assert_called_once_with(arg=10) + assert spy.side_effect == exc_info.value + + @skip_pypy def test_instance_method_by_class_spy(mocker): class Foo(object):