断言的功能/方法不是使用模拟叫(Assert a function/method was not c

2019-06-27 13:34发布

我使用的是模拟库来测试我的应用程序,但我想断言某些函数没有被调用。 模拟文档谈论类似的方法mock.assert_called_withmock.assert_called_once_with ,但我没有找到像什么mock.assert_not_called或东西来验证模拟相关的不叫

我可以像下面去了,虽然看起来很酷,也没有Python的它并不:

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

任何想法如何做到这一点?

谢谢你的帮助 :)

Answer 1:

这应该适用于你的情况;

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


Answer 2:

虽然一个老问题,我想补充一点,目前mock库(unittest.mock的反向移植)支持assert_not_called方法。

只要升级你的;

pip install mock --upgrade



Answer 3:

您可以检查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)


Answer 4:

当您使用测试类继承unittest.TestCase生成 ,你可以简单地使用类似的方法:

  • assertTrue
  • assertFalse
  • assertEqual便

和类似的(在Python文档 ,你找到的其余部分)。

在您的例子中,我们可以简单地断言,如果mock_method.called属性为False,这意味着该方法不叫。

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))


Answer 5:

从其他的答案来看,任何人,除非@抢坚谈到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和测试,如果它已经呼吁一些价值,但不能在其他人。



Answer 6:

随着python >= 3.5 ,你可以使用mock_object.assert_not_called()



文章来源: Assert a function/method was not called using Mock