Невозможно использовать attach_mock с макетом функции автоспецификации

Библиотечный модуль:

# mod.py
def foo():
    bar1("arg1")
    bar2("arg2x", "arg2y")

def bar1(x):
    pass

def bar2(x, y):
    pass

Тестовый модуль:

# test_mod.py
from mod import foo

def test_foo(mocker):
    mock = mocker.MagicMock()
    mock.attach_mock(mocker.patch("mod.bar1"), "b1")
    mock.attach_mock(mocker.patch("mod.bar2", autospec=True), "b2")
    foo()
    mock.assert_has_calls(
        [
            mocker.call.b1("arg1"),
            mocker.call.b2("arg2x", "arg2y"),
        ]
    )

The mocker fixture is from pytest-mock plugin. Execute the MCVE with python -m pytest.

Этот тест не проходит для странныйпричины.

E       AssertionError: Calls not found.
E       Expected: [call.b1('arg1'), call.b2('arg2x', 'arg2y')]
E       Actual: [call.b1('arg1')]

Без автоспек все работает. Нарушает ли использование autospec функцию attach_mock? Как должен тест для foo утверждать порядок и аргументы вызовов зависимостей bar1 и bar2не теряя своих автоспец.?

Хм, похоже, mocker.patch("mod.bar2", autospec=True) вообще не пропатчил функцию — можете проверить?

hoefling 29.05.2019 21:57

@hoefling Что заставляет тебя так говорить? Это действительно макет, но автоспецификация делает макет более похожим на оригинал, чем обычно. Поместите 1/0 внутри тела bar2, если хотите убедиться в этом.

wim 29.05.2019 22:08
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
2
203
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

На самом деле это была ошибка в Python. Это было исправлено в конце 2019 года, пропатченные версии:

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

Это соответствующие PR и ссылки на трекеры проблем:

бпо-21478: Функции Autospec должны распространять фиктивные вызовы родительским

бпо-21478: Записывайте вызовы родителя, когда объекты с автоматическим определением используются как дочерние с помощью attach_mock

бпо-38473: Обрабатывать автоматически заданные функции и методы, используемые с attach_mock

Нашивка Картикеяна Сингаравелана.

Другие вопросы по теме