From 25de8529a9f94047cbaa53c550647afdf2754a3d Mon Sep 17 00:00:00 2001 From: Inderpreet Singh Date: Wed, 27 Nov 2019 15:05:32 -0500 Subject: [PATCH 1/6] Store raised exceptions in return_value for spies --- src/pytest_mock/plugin.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/pytest_mock/plugin.py b/src/pytest_mock/plugin.py index dda073a..00b5bf7 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.return_value = e + raise + else: + result.return_value = r return r result = self.patch.object(obj, name, side_effect=wrapper, autospec=autospec) From 0df91f972f739b91200f75219fe1b980141517b7 Mon Sep 17 00:00:00 2001 From: Inderpreet Singh Date: Wed, 27 Nov 2019 15:06:58 -0500 Subject: [PATCH 2/6] Add spy exception catching --- tests/test_pytest_mock.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/test_pytest_mock.py b/tests/test_pytest_mock.py index dd8c3a9..1a00167 100644 --- a/tests/test_pytest_mock.py +++ b/tests/test_pytest_mock.py @@ -243,6 +243,24 @@ 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.return_value == exc_info.value + + @skip_pypy def test_instance_method_by_class_spy(mocker): class Foo(object): From b3e0ad5301bdd21bce72d5297d60ad5a322cce9b Mon Sep 17 00:00:00 2001 From: Inderpreet Singh Date: Wed, 27 Nov 2019 15:16:40 -0500 Subject: [PATCH 3/6] Black linting --- tests/test_pytest_mock.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_pytest_mock.py b/tests/test_pytest_mock.py index 1a00167..c4be922 100644 --- a/tests/test_pytest_mock.py +++ b/tests/test_pytest_mock.py @@ -245,6 +245,7 @@ def bar(self, arg): def test_instance_method_spy_exception(mocker): excepted_message = "foo" + class Foo(object): def bar(self, arg): raise Exception(excepted_message) From 50f99e56a48a2dcdca87078546cc658c08346b44 Mon Sep 17 00:00:00 2001 From: Inderpreet Singh Date: Mon, 2 Dec 2019 11:20:02 -0500 Subject: [PATCH 4/6] Record exceptions as side effects for spies --- src/pytest_mock/plugin.py | 2 +- tests/test_pytest_mock.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pytest_mock/plugin.py b/src/pytest_mock/plugin.py index 00b5bf7..470072b 100644 --- a/src/pytest_mock/plugin.py +++ b/src/pytest_mock/plugin.py @@ -116,7 +116,7 @@ def wrapper(*args, **kwargs): try: r = method(*args, **kwargs) except Exception as e: - result.return_value = e + result.side_effect = e raise else: result.return_value = r diff --git a/tests/test_pytest_mock.py b/tests/test_pytest_mock.py index c4be922..04261f5 100644 --- a/tests/test_pytest_mock.py +++ b/tests/test_pytest_mock.py @@ -259,7 +259,7 @@ def bar(self, arg): assert str(exc_info.value) == excepted_message foo.bar.assert_called_once_with(arg=10) - assert spy.return_value == exc_info.value + assert spy.side_effect == exc_info.value @skip_pypy From 567e053265609689b9692d331d2ddd8d63fe2289 Mon Sep 17 00:00:00 2001 From: Inderpreet Singh Date: Thu, 5 Dec 2019 18:16:03 -0500 Subject: [PATCH 5/6] Add docs for side effect feature on spies --- CHANGELOG.rst | 6 ++++++ README.rst | 3 +++ 2 files changed, 9 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d40165b..c115067 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,9 @@ +1.13.0 +------ + +* 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 3b2c587..61b6eb9 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 ---- From 895efb1369765ddf16fb6e3bf47d317444eff4d2 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 5 Dec 2019 22:43:52 -0300 Subject: [PATCH 6/6] Add date to changelog for version 1.13.0 --- CHANGELOG.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c115067..ab7cf60 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,5 +1,5 @@ -1.13.0 ------- +1.13.0 (2019-12-05) +------------------- * The object returned by ``mocker.spy`` now also tracks any side effect of the spied method/function.