pytest-mock 1.13.0: catching side-effects breaks spy
See original GitHub issueHello,
Since #173 was merged (and pytest-mock 1.13.0 released), mocker.spy
can’t be called successfully once a spied function raised an exception.
The issue is that mocker.spy
relies on a side-effect to wrap all the calls: https://github.com/pytest-dev/pytest-mock/blob/7bddcd53d287a59150d22e6496bcf20af44c3378/src/pytest_mock/plugin.py#L125
But now that we assign a new side-effect after an exception was raised, the spy will always raise the exception instead of calling the wrapper.
Here is a test case to reproduce the issue:
def test_spy_side_effect(mocker):
class Foo:
def bar(self, arg):
if arg > 0:
return arg
raise RuntimeError("I'm an error")
foo = Foo()
mocker.spy(foo, 'bar')
assert foo.bar(42) == 42
foo.bar.assert_called_with(42)
with pytest.raises(RuntimeError) as exc_info:
foo.bar(-1)
assert str(exc_info.value) == "I'm an error"
foo.bar.assert_called_with(-1)
# with pytest-mock 1.13.0 this will raise a RuntimeError instead of returning 21
assert foo.bar(21) == 21
foo.bar.assert_called_with(21)
A possible solution would be to assign the exception to result.return_value
instead of result.side_effect
as proposed initially in #173. However I understand that this is not perfect either.
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (4 by maintainers)
Top Results From Across the Web
pytest-mock - PyPI
This plugin provides a mocker fixture which is a thin-wrapper around the patching API provided by the mock package: import os class UnixFS:...
Read more >pkg_desc_index « metadata - repo/sync/gentoo.git
1: Package maintenance system for Debian app-arch/duff 0.5. · 2: Command-line utility for quickly finding duplicates in a given set of files app-arch/dump...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Fixed in
2.0.0
🎉@nicoddemus, I agree with using
spy_exception_raised
. I generally prefer these spy-special goodies in appropriately-named attributes.As a side note, overriding
return_value
is also not perfectly ideal.return_value
will return theMagicMock
object before any calls made to the spy. Though after a spy is invoked,return_value
will get overridden by our pytest-mock code. The problem with this behavior is it makes it tough to make easy-enough assertions. One would have to do something along the lines ofassert type(spy.return_value) is not type(MagicMock)
(or maybe checkmock_calls
orcall_count
to see if its usable) to ensure that we actually can use thereturn_value
. Furthermore, if the spied method returns a MagicMock or if an exception is thrown, thereturn_value
will continue to being some type ofMagicMock
. Gets a bit tough to reason about. I would prefer if we hadspy_return_value
as well on that side to make it perfectly clear.Finally, @k4nar seems to have found the bug that kept me from implementing a spy that could catch multiple call results. Won’t need to figure out much there anymore. Thanks!