Ronny Efronny
Ronny Efronny

Reputation: 1498

Pytest Monkeypatch Doesn't Apply To Imported Function

I have a module set up roughly as follows:

# foo.py
def generate_things_based_on_other_things():
  # some nasty things here

# bar.py
from foo import generate_things_based_on_other_things as generate

def coo():
  generate()

# conftest.py
import pytest

@pytest.fixture(autouse=True)
def patch_generate(monkeypatch):
  def mock_generate():
    print("hello!")

  monkeypatch.setattr("app.bar.generate", mock_generate)

# test_bar.py
from bar import coo

def test_coo():
  coo()

As per this answer I made sure to monkeypatch the actual imported instance of the function. Any other path throws a "does not exist on module" error. However when I run the test I hit an error, because the original function generate is being called, despite it being monkeypatched. I can't figure out why this patch won't stick the way I expect it too. I would expect this test to print "hello!".

Upvotes: 2

Views: 2207

Answers (1)

MrBean Bremen
MrBean Bremen

Reputation: 16805

Your paths seem not to match. You do from bar import coo, but use setattr with app.bar. To be sure, you can use the other form of setattr instead, which takes the object and the attribute names separately, e.g.:

import bar  # or "from app import bar", whichever is correct for you

@pytest.fixture(autouse=True)
def patch_generate(monkeypatch):
    def mock_generate():
        print("hello!")

    monkeypatch.setattr(bar, "generate", mock_generate)

This way you can be reasonably sure that you are patching the correct object.

Upvotes: 1

Related Questions