Skip to content

Commit 19a4e4d

Browse files
authored
Raise an error if mocker is used in a with context (#165)
Raise an error if mocker is used in a `with` context
2 parents 93b7ae3 + dcfc8ba commit 19a4e4d

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

CHANGELOG.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
1.11.2 (unreleased)
1+
1.11.2 (2019-10-19)
22
-------------------
33

44
* The *pytest introspection follows* message is no longer shown
55
if there is no pytest introspection (`#154`_).
66
Thanks `@The-Compiler`_ for the report.
77

8+
* ``mocker`` now raises a ``TypeError`` when used as a context-manager.
9+
Thanks `@binarymason`_ for the PR (`#165`_).
10+
811
.. _#154: https://github.com/pytest-dev/pytest-mock/issues/154
12+
.. _#165: https://github.com/pytest-dev/pytest-mock/pull/165
13+
.. _@binarymason: https://github.com/binarymason
914

1015
1.11.1 (2019-10-04)
1116
-------------------

src/pytest_mock/plugin.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,22 @@ def _start_patch(self, mock_func, *args, **kwargs):
156156

157157
def object(self, *args, **kwargs):
158158
"""API to mock.patch.object"""
159+
self._enforce_no_with_context(inspect.stack())
159160
return self._start_patch(self.mock_module.patch.object, *args, **kwargs)
160161

162+
def _enforce_no_with_context(self, stack):
163+
"""raises a ValueError if mocker is used in a with context"""
164+
caller = stack[1]
165+
frame = caller[0]
166+
info = inspect.getframeinfo(frame)
167+
code_context = " ".join(info.code_context).strip()
168+
169+
if code_context.startswith("with mocker."):
170+
raise ValueError(
171+
"Using mocker in a with context is not supported. "
172+
"https://github.com/pytest-dev/pytest-mock#note-about-usage-as-context-manager"
173+
)
174+
161175
def multiple(self, *args, **kwargs):
162176
"""API to mock.patch.multiple"""
163177
return self._start_patch(self.mock_module.patch.multiple, *args, **kwargs)

tests/test_pytest_mock.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,3 +721,22 @@ def test_get_random_number(mocker):
721721
result = testdir.runpytest_subprocess()
722722
result.stdout.fnmatch_lines("* 1 passed in *")
723723
assert "RuntimeError" not in result.stderr.str()
724+
725+
726+
def test_abort_context_manager(mocker):
727+
class A(object):
728+
def doIt(self):
729+
return False
730+
731+
a = A()
732+
733+
with pytest.raises(ValueError) as excinfo:
734+
with mocker.patch.object(a, "doIt", return_value=True):
735+
assert a.doIt() == True
736+
737+
expected_error_msg = (
738+
"Using mocker in a with context is not supported. "
739+
"https://github.com/pytest-dev/pytest-mock#note-about-usage-as-context-manager"
740+
)
741+
742+
assert str(excinfo.value) == expected_error_msg

0 commit comments

Comments
 (0)