monkeypatch функция, которую нужно импортировать в conftest - PullRequest
0 голосов
/ 25 марта 2019

Я пытаюсь использовать 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

1 Ответ

1 голос
/ 25 марта 2019

У вас есть прямой доступ к атрибуту, который вы хотите изменить.Вам вообще не нужен monkeypatch.

Вот мое дерево:

$ 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 =============================================================================================
...