Merged in ticosax/pytest/mock-unittest-252 (pull request #184)

Injection of fixture doesn't work when decorated with unittest.mock.patch
This commit is contained in:
holger krekel 2014-07-28 10:31:31 +02:00
commit 8792261df1
2 changed files with 44 additions and 7 deletions

View File

@ -1861,6 +1861,29 @@ class FixtureDef:
return ("<FixtureDef name=%r scope=%r baseid=%r >" %
(self.argname, self.scope, self.baseid))
def handle_mock_module_patching(function, startindex):
"""
Special treatment when test_function is decorated
by mock.patch
"""
for candidate_module_name in ('mock', 'unittest.mock'):
# stdlib comes last, because mock might be also installed
# as a third party with upgraded version compare to
# unittest.mock
try:
mock = sys.modules[candidate_module_name]
except KeyError:
pass
else:
for patching in getattr(function, "patchings", []):
if (not patching.attribute_name
and patching.new is mock.DEFAULT):
startindex += 1
break
else:
startindex += len(getattr(function, "patchings", []))
return startindex
def getfuncargnames(function, startindex=None):
# XXX merge with main.py's varnames
#assert not inspect.isclass(function)
@ -1870,13 +1893,7 @@ def getfuncargnames(function, startindex=None):
if startindex is None:
startindex = inspect.ismethod(function) and 1 or 0
if realfunction != function:
mock = sys.modules.get('mock')
if mock is not None:
for patching in getattr(function, "patchings", []):
if not patching.attribute_name and patching.new is mock.DEFAULT:
startindex += 1
else:
startindex += len(getattr(function, "patchings", []))
startindex = handle_mock_module_patching(function, startindex)
function = realfunction
argnames = inspect.getargs(py.code.getrawcode(function))[0]
defaults = getattr(function, 'func_defaults',

View File

@ -112,6 +112,26 @@ class TestMockDecoration:
reprec = testdir.inline_run()
reprec.assertoutcome(passed=1)
def test_unittest_mock_and_fixture(self, testdir):
pytest.importorskip("unittest.mock")
testdir.makepyfile("""
import os.path
import unittest.mock
import pytest
@pytest.fixture
def inject_me():
pass
@unittest.mock.patch.object(os.path, "abspath",
new=unittest.mock.MagicMock)
def test_hello(inject_me):
import os
os.path.abspath("hello")
""")
reprec = testdir.inline_run()
reprec.assertoutcome(passed=1)
def test_mock(self, testdir):
pytest.importorskip("mock", "1.0.1")
testdir.makepyfile("""