Игнорировать цепочечные вызовы в assert_has_calls с помощью pytest mocker - PullRequest
0 голосов
/ 17 сентября 2018

При использовании mocker из pytest-mock, как я могу использовать has_calls для проверки вызовов определенного метода без проверки всех вызовов, сделанных для возвращаемого значения этого метода?

Например:

import subprocess
from unittest import mock

def test_foo(mocker):
    m = mocker.patch('test_main.subprocess')
    r1 = subprocess.run(['foo'])
    r1.check_returncode()
    r2 = subprocess.run(['bar'])
    r2.check_returncode()

    m.run.assert_has_calls([
        mock.call(['foo']),
        mock.call(['bar']),
    ])

Сбой с:

E       AssertionError: Calls not found.
E       Expected: [call(['foo']), call(['bar'])]
E       Actual: [call(['foo']),
E        call().check_returncode(),
E        call(['bar']),
E        call().check_returncode()]

Почему звонки на возвращаемое значение также включены? Я просто хочу убедиться, что мне позвонили на subprocess.run(['foo']) , а затем на subprocess.run(['bar']). Меня не волнуют звонки на все, что он возвращает, но я делаю забочусь о порядке звонков самой run.

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Использование assert_any_call:

m.run.assert_any_call(['foo'])
m.run.assert_any_call(['bar'])
0 голосов
/ 18 сентября 2018

Добавьте any_order=True к вашему assert_has_calls вызову, например:

m.run.assert_has_calls([
    mock.call(['foo']),
    mock.call(['bar']),
], any_order=True)

Причина в том, что, похоже, assert_has_calls использует атрибут mock_calls на макете, который основан на документации (https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.mock_calls):

записывает все вызовы фиктивного объекта, его методы, магические методы и макеты возвращаемого значения.

С assert_has_calls, однако, это не проблема с точным соответствием, это был просто сбой упорядочивания.

РЕДАКТИРОВАТЬ: Поскольку порядок имеет значение, используйте call_args_list. Как это:

def test_foo(mocker):
    m = mocker.patch('subprocess_test.subprocess')
    r1 = subprocess.run(['foo'])
    r1.check_returncode()
    r2 = subprocess.run(['bar'])
    r2.check_returncode()

    assert [mock.call(['foo']), mock.call(['bar'])] == m.run.call_args_list
...