theberzi
theberzi

Reputation: 2645

mock.patch in pytest fixture doesn't work when other tests have run

Given the following code and tests:

# some module

from other.module import a_func  # returns False by default


def do_stuff():
    return "banana" if a_func() else "pear"

#############################

# tests in a different module

@pytest.fixture
def my_fixture():
    with mock.patch("other.module.a_func", lambda: True):
        yield


class TestMyStuff:
    def test_something(self):
        assert do_stuff() == "pear"

    def test_something_else(self, my_fixture):
        assert do_stuff() == "banana"

The last test fails if I run all my tests at once, but succeeds if I only run it.

I know that this might be due to the fact that by the time test_something_else runs, other.module.a_func has already been imported and loaded, and so the patch isn't taking effect.

How do I make it work, or how should I restructure my code so that I can mock the result of a_func to test different outcomes of do_stuff?

Upvotes: 10

Views: 5082

Answers (1)

hoefling
hoefling

Reputation: 66181

You should do

mock.patch("some.module.a_func")

instead of

mock.patch("other.module.a_func")

from other.module import a_func means that a_func becomes part of the some.module, so patching the origin of function definition has no effect - instead, patching should be done where the function is used. Read Where to patch for more info.

Upvotes: 12

Related Questions