4 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/761d60bd87a6/ Changeset: 761d60bd87a6 Branch: mock-unittest-252 User: ticosax Date: 2014-07-26 17:26:18 Summary: Injection of fixture doesn't work when decorated with unittest.mock.patch
This is a continuation of #182 Affected #: 1 file diff -r 853ffb854a4813a6a2f9e0ad4229dde770f6c7a8 -r 761d60bd87a6794d9a25ca48aa7dff968ffc415b testing/python/integration.py --- a/testing/python/integration.py +++ b/testing/python/integration.py @@ -112,6 +112,26 @@ 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(""" https://bitbucket.org/hpk42/pytest/commits/15115d747734/ Changeset: 15115d747734 Branch: mock-unittest-252 User: ticosax Date: 2014-07-27 10:43:50 Summary: Handle also unittest.mock Move handling in dedicated function to isolate its logic Affected #: 1 file diff -r 761d60bd87a6794d9a25ca48aa7dff968ffc415b -r 15115d747734b6431805e32411fa95999402502a _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1861,6 +1861,27 @@ 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 ('unittest.mock', 'mock'): + # stdlib comes first + 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 +1891,7 @@ 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', https://bitbucket.org/hpk42/pytest/commits/06e38b54a90f/ Changeset: 06e38b54a90f Branch: mock-unittest-252 User: ticosax Date: 2014-07-27 12:11:39 Summary: unittest.mock from stdlib should come last Affected #: 1 file diff -r 15115d747734b6431805e32411fa95999402502a -r 06e38b54a90f9f7d74f3e5a28f0c0eeac7e44835 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1866,8 +1866,10 @@ Special treatment when test_function is decorated by mock.patch """ - for candidate_module_name in ('unittest.mock', 'mock'): - # stdlib comes first + 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: https://bitbucket.org/hpk42/pytest/commits/7b861c1de21d/ Changeset: 7b861c1de21d User: hpk42 Date: 2014-07-28 10:31:31 Summary: Merged in ticosax/pytest/mock-unittest-252 (pull request #184) Injection of fixture doesn't work when decorated with unittest.mock.patch Affected #: 2 files diff -r c49801c86150891478719d8ca94505da2cf3f4e8 -r 7b861c1de21df974bf015ee9b254bf266d73d300 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1861,6 +1861,29 @@ 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 @@ 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', diff -r c49801c86150891478719d8ca94505da2cf3f4e8 -r 7b861c1de21df974bf015ee9b254bf266d73d300 testing/python/integration.py --- a/testing/python/integration.py +++ b/testing/python/integration.py @@ -112,6 +112,26 @@ 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(""" Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. _______________________________________________ pytest-commit mailing list pytest-commit@python.org https://mail.python.org/mailman/listinfo/pytest-commit