Декодер @Patch не совместим с фитингом pytest

Я столкнулся с чем-то загадочным, когда использовал патч-декоратор из макетного пакета, интегрированного с фитингом pytest.

У меня есть два модуля

    -----test folder
          -------func.py
          -------test_test.py

в func.py:

    def a():
        return 1

    def b():
        return a()     

в test_test.py

    import pytest
    from func import a,b
    from mock import patch,Mock

    @pytest.fixture(scope="module")
    def brands():
        return 1


    mock_b=Mock()

    @patch('test_test.b',mock_b)
    def test_compute_scores(brands):                 
         a()

Кажется, что исправление патча несовместимо с фитингом pytest. Кто-нибудь знает об этом? Tnanks

Ответ 1

У меня была та же проблема, и решение для меня состояло в том, чтобы использовать mock library в версии 1.0.1 (до того, как я использовал unittest.mock в версии 2.6.0). Теперь это работает как шарм :)

Ответ 2

Это не касается вашего вопроса напрямую, но есть плагин pytest-mock, который позволяет вам написать это вместо этого:

def test_compute_scores(brands, mock):                 
     mock_b = mock.patch('test_test.b')
     a()

Ответ 3

Надеюсь, этот ответ по старому вопросу поможет кому-то.

Во-первых, вопрос не включает ошибку, поэтому мы действительно не знаем, что происходит. Но я постараюсь предоставить что-то, что помогло мне.

Если вам нужен тест, украшенный исправленным объектом, то для его работы с pytest вы можете просто сделать это:

@mock.patch('mocked.module')
def test_me(*args):
    mocked_module = args[0]

Или для нескольких патчей:

@mock.patch('mocked.module1')
@mock.patch('mocked.module')
def test_me(*args):
    mocked_module1, mocked_module2 = args

pytest ищет имена приборов для поиска в тестовой функции/методе. Предоставление *args дает нам хорошую обходную фазу поиска. Итак, чтобы включить светильник с патчами, вы можете сделать это:

# from question
@pytest.fixture(scope="module")
def brands():
    return 1

@mock.patch('mocked.module1')
def test_me(brands, *args):
    mocked_module1 = args[0]

Это помогло мне запустить python 3.6 и pytest 3.0.6.

Ответ 4

Начиная с Python3.3, модуль mock был unittest библиотеку unittest. Существует также бэкпорт (для предыдущих версий Python), доступный как автономный mock библиотеки.

Объединение этих двух библиотек в один и тот же набор тестов дает вышеупомянутую ошибку:

E       fixture 'fixture_name' not found

В вашей виртуальной среде тестового набора запустите pup uninstall pip uninstall mock и убедитесь, что вы не используете бэкпортированную библиотеку вместе с основной библиотекой unittest. Когда вы повторно запускаете свои тесты после удаления, вы увидите ImportError если это так.

Замените все экземпляры этого импорта с помощью from unittest.mock import <stuff>.

Ответ 5

При использовании pytest fixture с mock.patch, параметр порядка испытаний имеет решающее значение.

Если вы заказываете светильник перед издевательством:

from unittest import mock

    @mock.patch(
        'my.module.my.class',
    )
    def test_my_code(
        my_fixture,
        mocked_class,
    ):

mock object будет в my_fixture а mocked_class будет искать в качестве инструмента:

fixture 'mocked_class' not found

Но, если вы закажете параметр fixture в конце:

from unittest import mock

    @mock.patch(
        'my.module.my.class',
    )
    def test_my_code(
        mocked_class,
        my_fixture,
    ):

Эл будет хорошо.