Skip to content

Commit

Permalink
Raise an error if mocker is used in a with context
Browse files Browse the repository at this point in the history
Ref: #164
  • Loading branch information
binarymason committed Oct 22, 2019
1 parent 93b7ae3 commit 72f66b0
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/pytest_mock/plugin.py
Expand Up @@ -156,8 +156,22 @@ def _start_patch(self, mock_func, *args, **kwargs):

def object(self, *args, **kwargs):
"""API to mock.patch.object"""
self._enforce_no_with_context(inspect.stack())
return self._start_patch(self.mock_module.patch.object, *args, **kwargs)

def _enforce_no_with_context(self, stack):
"""raises a ValueError if mocker is used in a with context"""
caller = stack[1]
frame = caller[0]
info = inspect.getframeinfo(frame)
code_context = " ".join(info.code_context).strip()

if "with mocker" in code_context:
raise ValueError(
"Using mocker in a with context is not supported. "
"https://github.com/pytest-dev/pytest-mock#note-about-usage-as-context-manager"
)

def multiple(self, *args, **kwargs):
"""API to mock.patch.multiple"""
return self._start_patch(self.mock_module.patch.multiple, *args, **kwargs)
Expand Down
19 changes: 19 additions & 0 deletions tests/test_pytest_mock.py
Expand Up @@ -721,3 +721,22 @@ def test_get_random_number(mocker):
result = testdir.runpytest_subprocess()
result.stdout.fnmatch_lines("* 1 passed in *")
assert "RuntimeError" not in result.stderr.str()


def test_abort_context_manager(mocker):
class A(object):
def doIt(self):
return False

a = A()

with pytest.raises(ValueError) as excinfo:
with mocker.patch.object(a, "doIt", return_value=True):
assert a.doIt() == True

expected_error_msg = (
"Using mocker in a with context is not supported. "
"https://github.com/pytest-dev/pytest-mock#note-about-usage-as-context-manager"
)

assert str(excinfo.value) == expected_error_msg

0 comments on commit 72f66b0

Please sign in to comment.