I'm trying to use pytest.monkeypatch
to patch a function I've defined in another file. I then need to patch a function from another that relies on this first monkeypatch
. Here's a simple example
# class_def.py
class C:
def __init__(self):
# Normally, there is something that makes self.p
# that will use a file that will exist on production
raise FileNotFoundError
def factory():
print('in factory')
return C()
----
# function_def.py
from .class_def import factory
foo = factory()
def bar():
return 0
----
# conftest.py
from unittest.mock import MagicMock
import pytest
import playground.class_def
@pytest.fixture(autouse=True)
def patch_c(monkeypatch):
fake_c = MagicMock()
def factory():
print('in monkey factory')
return fake_c
monkeypatch.setattr('playground.class_def.factory', factory)
from .function_def import bar
# Then I would patch bar
And running pytest .
will fail with FileNotFoundError
. I believe this happens because I am calling foo = factory()
at the top level of function_def.py
. I expected this not to happen because I am patching factory
before doing this import, but that doesn't seem to be happening. Is there a way to ensure this monkeypatch.setattr
will go into effect before from .function_def import bar
in conftest.py
?
Also, the file structure looks like
playground
|--- __init__.py
|--- conftest.py
|--- class_def.py
|--- function_def
You have direct access to the attribute you want to change. You don't need monkeypatch at all.
Here's my tree :
$ tree .
.
├── a.py
├── b.py
├── __init__.py
└── test_a.py
0 directories, 4 files
a.py
class A:
def __init__(self):
raise Exception
def factory():
return A()
b.py
import a
print(a.factory())
test_a.py
import a
def test_a():
def fake_factory():
return 'A'
a.factory = fake_factory
import b
And it works:
$ pytest
=============================================================================================== test session starts ===============================================================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: /home/ahorgnies/test/monkeypatch, inifile:
plugins: remotedata-0.2.1, openfiles-0.3.0, doctestplus-0.1.3, arraydiff-0.2
collected 1 item
test_a.py . [100%]
============================================================================================ 1 passed in 0.01 seconds =============================================================================================