我正在尝试使用pytest.monkeypatch
修补我在另一个文件中定义的功能。然后,我需要从依赖此第一个monkeypatch
的另一个函数中打补丁。这是一个简单的例子
# 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
运行pytest .
将失败,并显示FileNotFoundError
。我相信发生这种情况是因为我在foo = factory()
的顶层调用function_def.py
。我希望不会发生这种情况,因为我在进行此导入之前先对factory
进行了修补,但这似乎没有发生。是否有办法确保此monkeypatch.setattr
在from .function_def import bar
中的conftest.py
之前生效?
此外,文件结构看起来像
playground
|--- __init__.py
|--- conftest.py
|--- class_def.py
|--- function_def
答案 0 :(得分:1)
您可以直接访问要更改的属性。您根本不需要猴子补丁。
这是我的树:
$ 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
它有效:
$ 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 =============================================================================================