从其他答案来看,除了@ 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的元组进行比较,其中第一个组件是包含相关调用的所有位置参数的元组,而第二个组件是关键字arguments的字典。
>>> ((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
您不仅可以通过检查是否已调用了模拟的可调用对象,还可以通过一组特定的参数来检查它是否已被调用。
这很有用。假设您要测试一个接受列表的函数,然后compute()
仅在满足特定条件的情况下针对列表的每个值调用另一个函数。
现在compute
,您可以模拟,并测试是否已按某个值调用了它,但未按其他值调用了它。