Единичное тестирование: как утверждать несколько вызовов одного и того же метода?

У меня есть метод, который вызывает другой метод дважды, с разными аргументами.

class A(object):
    def helper(self, arg_one, arg_two):
        """Return something which depends on arguments."""

    def caller(self):
        value_1 = self.helper(foo, bar)  # First call.
        value_2 = self.helper(foo_bar, bar_foo)  # Second call!

Использование assert_called_with помогает мне утверждать только первый вызов, а не второй. Даже assert_called_once_with не кажется полезным. Что мне здесь не хватает? Есть ли способ проверить такие звонки?

Ответ 1

Вы можете использовать mock_calls который содержит все вызовы, сделанные для метода. Этот список содержит первый вызов, второй вызов и все последующие вызовы. Таким образом, вы можете писать утверждения с помощью mock_calls[1] чтобы указать что-то о втором вызове.


Например, если m = mock.Mock() и код выполняет m.method(123) то вы пишете:

assert m.method.mock_calls == [mock.call(123)]

который утверждает, что список вызовов m.method - это ровно один вызов, а именно вызов с аргументом 123.

Ответ 2

Чтобы добавить к ответу Саймона Виссера, вы можете использовать метод unittest.TestCase self.assertEqual() вместо синтаксиса assert, который, я бы сказал, является лучшей практикой в контексте Unit Test, поскольку вы также можете добавлять к нему комментарии, которые будут отображаться всякий раз, когда что-то идет не так.

Так, например:

self.assertEqual(
    [
        mock.call(1, 'ValueA', True)),
        mock.call(2, 'ValueB', False)),
        mock.call(3, 'ValueC', False))
    ],
    mock_cur.execute.mock_calls,
    "The method was not called with the correct arguments."
)