pytest-mock: издевательство не работает, когда выполняется без приспособления, и импорт является глобальным

#python #unit-testing #pytest #pytest-mock

#python #модульное тестирование #pytest #pytest-mock

Вопрос:

Я использую PyCharm Pro, и у меня есть интерпретатор Python, настроенный на удаленный интерпретатор из Docker.

Структура моего проекта такая

 ├── helpers.py
├── package1
│   ├── helper_functions.py
│   └── __init__.py
├── package2
│   ├── helpers_functions.py
│   ├── __init__.py
└── tests
    ├── conftest.py
    ├── __init__.py
    ├── package1
    │   ├── conftest.py
    │   ├── __init__.py
    │   ├── test_helper_functions.py
    └── package2
        ├── conftest.py
        ├── __init__.py

 

Я использую pytest и pytest-mock .

Я определяю тест tests/package1/test_helper_functions.py для тестирования package1.helper_functions.helper_func1 , который вызывает функцию helpers.some_long_operation , эту функцию я хочу издеваться.

Так я и делаю.

 # package1/helper_functions.py

from helpers import some_long_operation

def helper_func1():
    return some_long_operation()
 
 # tests/package1/test_helper_functions.py

from package1.helper_functions import helper_func1

def test_helper_func1(mocker):
    mocker.patch("helpers.some_long_operation", return_value={})
    assert helper_func1() == {}
 

Поэтому, когда я выполняю тест helpers.some_long_operation , вызывается оригинал.

Однако, когда я создаю приспособление conftest.py и импортирую функцию локально в тестовую функцию, макет работает, а исходная функция не вызывается.

Итак, я создаю приспособление в tests/package1/conftest.py

 # tests/package1/conftest.py

import pytest

@pytest.fixture
def mocked_some_long_operation(mocker):
    mocker.patch("helpers.some_long_operation", return_value={})
 

И я использую это приспособление в тестировании и импортирую package1.helper_functions.helper_func1 локально внутри функции.

 # tests/package1/test_helper_functions.py


def test_helper_func1(mocked_some_long_operation):
    from package1.helper_functions import helper_func1
    assert helper_func1() == {}
 

Теперь я в порядке, что это работает сейчас, но мне любопытно, почему это происходит.

Комментарии:

1. Вы исправляете неправильную ссылку — смотрите, где нужно исправить . patch("package1.helper_functions.some_long_operation") Вместо этого должно работать что-то вроде.

2. @MrBeanBremen Да, это было недостающее звено, но почему оно работает, когда я перемещаю это на conftest.py .

3. Потому что импорт conftest.py происходит раньше package1/helper_functions.py .