pytest-dev / pytest-dev/pytest

unittest.mock's patch.multiple being interpreted as fixtures

Open
#8,748 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

plugin: unittest topic: fixtures
Dominant language
Python
Stars
14.5k
Forks
3.4k
Avg merge
2d 9h
Merged PRs (30d)
35

Description

From pytest's docs on unittest.TestCase support:

pytest supports running Python unittest-based tests out of the box.

However, I think I have a case where TestCase is not properly supported: unittest.mock's patch.multiple.

From the unittest.mock's docs on patch.multiple:

@patch.multiple('__main__', thing=DEFAULT, other=DEFAULT)
def test_function(thing, other):

You can break out the patches into args for a test function. However, this doesn't seem to work with pytest, as it interprets thing and other as fixtures.

Minimal Repro

from unittest import TestCase
from unittest.mock import DEFAULT, MagicMock, patch

class Foo:
    def bar(self) -> None:
        pass

class TestFoo1(TestCase):
    @patch.multiple(Foo, bar=DEFAULT)
    def test_patch_multiple(self, bar: MagicMock) -> None:
        """Works when subclassing TestCase."""

class TestFoo2:
    @patch.multiple(Foo, bar=DEFAULT)
    def test_patch_multiple(self, bar: MagicMock) -> None:
        """Fails when not subclassing TestCase."""

Here is the output when running pytest

patch_multiple.py::TestFoo2::test_patch_multiple ERROR                   [100%]
test setup failed
file /path/to/patch_multiple.py, line 14
      @patch.multiple(Foo, bar=DEFAULT)
      def test_patch_multiple(self, bar: MagicMock) -> None:
E       fixture 'bar' not found

By subclassing TestCase, pytest doesn't interpret bar as a fixture, and the test runs. Are there any known workarounds to stop pytest from interpreting bar as a fixture?

Versions

I am using macOS Catalina version 10.15.7.

Python==3.7.7
pytest==6.2.4

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the minimal reproduction from the issue and compare pytest's handling of the TestFoo1 and TestFoo2 methods. Trace fixture argument discovery for the non-TestCase method, then add a regression test showing that arguments supplied by unittest.mock.patch.multiple are not treated as fixtures.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.