monkeypatch需要在conftest中导入的函数

时间:2019-03-25 13:23:16

标签: python pytest monkeypatching

我正在尝试使用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.setattrfrom .function_def import bar中的conftest.py之前生效?

此外,文件结构看起来像

playground
|--- __init__.py
|--- conftest.py
|--- class_def.py
|--- function_def

1 个答案:

答案 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 =============================================================================================
相关问题