From b6166dccb4d2b48173aa7e7739be52db9d2d56a0 Mon Sep 17 00:00:00 2001 From: Marcin Bachry Date: Mon, 12 Feb 2018 18:41:00 +0100 Subject: [PATCH] Fix mock patchings detection when both mock and unittest.mock are present --- _pytest/compat.py | 7 ++++--- changelog/3206.bugfix.rst | 1 + testing/python/integration.py | 22 ++++++++++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 changelog/3206.bugfix.rst diff --git a/_pytest/compat.py b/_pytest/compat.py index 7560fbec3..92df65656 100644 --- a/_pytest/compat.py +++ b/_pytest/compat.py @@ -79,10 +79,11 @@ def num_mock_patch_args(function): patchings = getattr(function, "patchings", None) if not patchings: return 0 - mock = sys.modules.get("mock", sys.modules.get("unittest.mock", None)) - if mock is not None: + mock_modules = [sys.modules.get("mock"), sys.modules.get("unittest.mock")] + if any(mock_modules): + sentinels = [m.DEFAULT for m in mock_modules if m is not None] return len([p for p in patchings - if not p.attribute_name and p.new is mock.DEFAULT]) + if not p.attribute_name and p.new in sentinels]) return len(patchings) diff --git a/changelog/3206.bugfix.rst b/changelog/3206.bugfix.rst new file mode 100644 index 000000000..1e2305fa2 --- /dev/null +++ b/changelog/3206.bugfix.rst @@ -0,0 +1 @@ +Detect arguments injected by ``unittest.mock.patch`` decorator correctly when pypi ``mock.patch`` is installed and imported. diff --git a/testing/python/integration.py b/testing/python/integration.py index 6ea29fa98..aade04fa9 100644 --- a/testing/python/integration.py +++ b/testing/python/integration.py @@ -147,6 +147,28 @@ class TestMockDecoration(object): reprec = testdir.inline_run() reprec.assertoutcome(passed=1) + def test_unittest_mock_and_pypi_mock(self, testdir): + pytest.importorskip("unittest.mock") + pytest.importorskip("mock", "1.0.1") + testdir.makepyfile(""" + import mock + import unittest.mock + class TestBoth(object): + @unittest.mock.patch("os.path.abspath") + def test_hello(self, abspath): + import os + os.path.abspath("hello") + abspath.assert_any_call("hello") + + @mock.patch("os.path.abspath") + def test_hello_mock(self, abspath): + import os + os.path.abspath("hello") + abspath.assert_any_call("hello") + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2) + def test_mock(self, testdir): pytest.importorskip("mock", "1.0.1") testdir.makepyfile("""