断言一个函数/方法不是使用Mock调用的
我正在使用模拟库来testing我的应用程序,但我想断言一些函数没有被调用。 模拟文档讨论像mock.assert_called_with
和mock.assert_called_once_with
这样的方法,但是我没有发现任何类似mock.assert_not_called
或者相关的东西来validationmock 没有被调用 。
我可以像下面这样做,虽然看起来不酷,也不像pythonic:
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
任何想法如何做到这一点?
谢谢你的帮助 :)
这应该适合你的情况;
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
你可以检查被called
属性,但是如果你的断言失败了,接下来你想知道的是关于意外调用的东西,所以你可以安排从一开始就显示这些信息。 使用unittest
,你可以检查call_args_list
的内容:
self.assertItemsEqual(my_var.call_args_list, [])
当它失败时,它会给出这样的信息:
AssertionError:元素数不相等: 第一个有0,第二个有1:call('first argument',4)
虽然老问题,我想补充一点,目前mock
库( assert_not_called
backport)支持assert_not_called
方法。
只是升级你的;
pip install mock --upgrade
当你使用类inheritanceunittest.TestCasetesting时,你可以简单地使用如下的方法:
- assertTrue
- assertFalse
- assertEqual便
和类似的(在python文档中你可以find其他的)。
在你的例子中,我们可以简单地断言,如果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))
从其他答案来看,除了@ rob-kennedy之外没有人谈到call_args_list
。
这是一个强大的工具,你可以实现MagicMock.assert_called_with()
的完全相反
call_args_list
是一个call
对象列表。 每个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
所以,解决OP的具体问题的方法是
def test_something(): with patch('something') as my_var: assert ((some, args),) not in my_var.call_args_list
请注意,通过这种方式,不是只通过MagicMock.called
检查是否调用了一个MagicMock.called
可调用MagicMock.called
,现在可以检查是否使用了一组特定的参数调用它。
这很有用。 假设你想要testing一个带有列表的函数,并且只有满足一个特定的条件才能调用另一个函数compute()
。
你现在可以模拟compute
,并testing它是否被调用了一些值,而不是其他值。