Skip to content

Commit

Permalink
Merge pull request #216 from webknjaz/bugfixes/215-spy-on-keyboard-in…
Browse files Browse the repository at this point in the history
…terrupt

Ensure all the exceptions can be spied on
  • Loading branch information
nicoddemus committed Dec 15, 2020
2 parents 9e1464b + 0e6b221 commit 9640a36
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 6 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.rst
Expand Up @@ -3,8 +3,20 @@

* Add `mock.seal` alias to the `mocker` fixture (`#211`_). Thanks `@coiax`_ for the PR.

* Fixed spying on exceptions not covered by the ``Exception``
superclass (`#215`_), like ``KeyboardInterrupt`` -- PR `#216`_
by `@webknjaz`_.

Before the fix, both ``spy_return`` and ``spy_exception``
whenever such an exception happened. And after this fix,
``spy_exception`` is set to a correct value of an exception
that has actually happened.

.. _@coiax: https://github.com/coiax
.. _@webknjaz: https://github.com/sponsors/webknjaz
.. _#211: https://github.com/pytest-dev/pytest-mock/pull/211
.. _#215: https://github.com/pytest-dev/pytest-mock/pull/215
.. _#216: https://github.com/pytest-dev/pytest-mock/pull/216

3.3.1 (2020-08-24)
------------------
Expand Down
4 changes: 2 additions & 2 deletions src/pytest_mock/plugin.py
Expand Up @@ -114,7 +114,7 @@ def wrapper(*args, **kwargs):
spy_obj.spy_exception = None
try:
r = method(*args, **kwargs)
except Exception as e:
except BaseException as e:
spy_obj.spy_exception = e
raise
else:
Expand All @@ -126,7 +126,7 @@ async def async_wrapper(*args, **kwargs):
spy_obj.spy_exception = None
try:
r = await method(*args, **kwargs)
except Exception as e:
except BaseException as e:
spy_obj.spy_exception = e
raise
else:
Expand Down
22 changes: 18 additions & 4 deletions tests/test_pytest_mock.py
Expand Up @@ -2,7 +2,7 @@
import platform
import sys
from contextlib import contextmanager
from typing import Callable, Any, Tuple, Generator
from typing import Callable, Any, Tuple, Generator, Type
from unittest.mock import MagicMock

import pytest
Expand Down Expand Up @@ -235,17 +235,31 @@ def bar(self, arg):
assert spy.spy_return == 20


def test_instance_method_spy_exception(mocker: MockerFixture) -> None:
# Ref: https://docs.python.org/3/library/exceptions.html#exception-hierarchy
@pytest.mark.parametrize(
"exc_cls",
(
BaseException,
Exception,
GeneratorExit, # BaseException
KeyboardInterrupt, # BaseException
RuntimeError, # regular Exception
SystemExit, # BaseException
),
)
def test_instance_method_spy_exception(
exc_cls: Type[BaseException], mocker: MockerFixture,
) -> None:
class Foo:
def bar(self, arg):
raise Exception("Error with {}".format(arg))
raise exc_cls("Error with {}".format(arg))

foo = Foo()
spy = mocker.spy(foo, "bar")

expected_calls = []
for i, v in enumerate([10, 20]):
with pytest.raises(Exception, match="Error with {}".format(v)) as exc_info:
with pytest.raises(exc_cls, match="Error with {}".format(v)):
foo.bar(arg=v)

expected_calls.append(mocker.call(arg=v))
Expand Down

0 comments on commit 9640a36

Please sign in to comment.