Assert функция / метод не был вызван с помощью макета


Я использую макет библиотеки для тестирования моего приложения, но я хочу утверждать, что некоторые функции не были вызваны. Макетные документы говорят о таких методах, как mock.assert_called_with и mock.assert_called_once_with, но я не нашел ничего подобного mock.assert_not_called или что-то связанное с проверкой mock was не называется.

Я могу пойти с что-то вроде следующего, но он не кажется холодным, ни весть:

def test_something:
    # some actions
    with patch('something') as my_var:
        try:
            # args are not important. func should never be called in this test
            my_var.assert_called_with(some, args)
        except AssertionError:
            pass  # this error being raised means it's ok
    # other stuff

есть идеи, как это сделать?

Спасибо за любую помощь :)

5 94

5 ответов:

Это должно работать для вашего случая;

assert not my_var.called, 'method should not have been called'

образца;

>>> mock=Mock()
>>> mock.a()
<Mock name='mock.a()' id='4349129872'>
>>> assert not mock.b.called, 'b was called and should not have been'
>>> assert not mock.a.called, 'a was called and should not have been'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: a was called and should not have been

хоть и старый вопрос, я хотел бы добавить, что в настоящее время mock библиотека (backport of unittest.глумиться) поддерживает assert_not_called метод.

просто обновите ваш;

pip install mock --upgrade

вы можете проверить called атрибут, но если ваше утверждение не удается, следующее, что вы хотите знать, это что-то о неожиданный вызов, так что вы можете также организовать для этой информации, которая будет отображаться с самого начала. Используя unittest, вы можете проверить содержимое call_args_list вместо:

self.assertItemsEqual(my_var.call_args_list, [])

когда он терпит неудачу, он дает такое сообщение:

AssertionError: Element counts were not equal:
First has 0, Second has 1:  call('first argument', 4)

при тестировании с помощью класса наследует unittest.Пример вы можете просто использовать такие методы, как:

  • assertTrue
  • assertFalse
  • assertEqual

и подобные (в документация python вы найдете остальные).

в вашем примере мы можем просто утверждать, если mock_method.называется недвижимость ложные, что означает, что метод не был называемый.

import unittest
from unittest import mock

import my_module

class A(unittest.TestCase):
    def setUp(self):
        self.message = "Method should not be called. Called {times} times!"

    @mock.patch("my_module.method_to_mock")
    def test(self, mock_method):
        my_module.method_to_mock()

        self.assertFalse(mock_method.called,
                         self.message.format(times=mock_method.call_count))

судя по другим ответам, никто кроме @rob-kennedy поговорили о call_args_list.

это мощный инструмент для того, что вы можете реализовать точную противоположность MagicMock.assert_called_with()

call_args_list список call объекты. Каждый call объект представляет вызов, выполненный на издевательском вызываемом объекте.

>>> from unittest.mock import MagicMock
>>> m = MagicMock()
>>> m.call_args_list
[]
>>> m(42)
<MagicMock name='mock()' id='139675158423872'>
>>> m.call_args_list
[call(42)]
>>> m(42, 30)
<MagicMock name='mock()' id='139675158423872'>
>>> m.call_args_list
[call(42), call(42, 30)]

потребление call объект прост, так как вы можете сравнить его с кортежем длины 2, где первый компонент является кортежем, содержащим все позиционные аргументы связанного вызова, в то время как второй компонент является словарем ключевых аргументов.

>>> ((42,),) in m.call_args_list
True
>>> m(42, foo='bar')
<MagicMock name='mock()' id='139675158423872'>
>>> ((42,), {'foo': 'bar'}) in m.call_args_list
True
>>> m(foo='bar')
<MagicMock name='mock()' id='139675158423872'>
>>> ((), {'foo': 'bar'}) in m.call_args_list
True

таким образом, способ решения конкретной проблемы ОП является

def test_something():
    with patch('something') as my_var:
        assert ((some, args),) not in my_var.call_args_list

обратите внимание, что таким образом, вместо того, чтобы просто проверить, если издевались вызываемый был вызван, через MagicMock.called, теперь вы можете проверить, был ли он вызван с определенным набором аргументов.

это полезно. Скажем, вы хотите проверить функцию, которая принимает список и вызывает еще одна функция, compute() для каждого значения из списка, только если они удовлетворяют определенному условию.

теперь вы можете издеваться compute, и проверить, если он был вызван на некоторые значения, но не на другие.