Как правильно использовать mock call_args с Python unittest.mock? - PullRequest
3 голосов
/ 07 февраля 2020

Рассмотрим следующие файлы:

holy_hand_grenade.py

def count(one, two, five='three'):
    print('boom')

test_holy_hand_grenade.py

from unittest import mock
import holy_hand_grenade

def test_hand_grenade():
    mock_count = mock.patch("holy_hand_grenade.count", autospec=True)
    with mock_count as fake_count:
        fake_count(1, 2, five=5)

        # According to https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.call_args
        # this should work
        assert fake_count.call_args.kwargs['five'] == 5

Согласно документам, call_args должно быть:

Это либо None (если mock не был вызван), либо аргументы, с которыми последний раз вызывался mock. Это будет в форме кортежа: первый член, к которому также можно получить доступ через свойство args, это любые упорядоченные аргументы, с которыми вызывается mock (или пустой кортеж), и второй член, , который также может быть доступным через свойство kwargs, любые ключевые аргументы (или пустой словарь).

(выделение мое)

Но это взрывается у меня на лице, с TypeError: tuple indices must be integers or slices, not str

Гм. Нет?

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

assert isinstance(fake_count.call_args, (mock._Call,))

проходит, он должен иметь kwargs и args. И это ... ну, вроде как. Но они, кажется, на самом деле не правильные вещи:

assert isinstance(fake_count.call_args.kwargs, (mock._Call,))  #this works
assert isinstance(fake_count.call_args.kwargs, (dict,))  # doesn't work

Что я здесь не так делаю?

1 Ответ

2 голосов
/ 07 февраля 2020

Эта функция появилась в Python 3.8 в этой проблеме .

В документации 3.7 ее нет (в то время как в новейших документах ) do) - поэтому вам нужно получить доступ к аргументам по индексу в Python <3.8. </p>

...