[英]How to get the arguments from a method call on a mocked object?
我有一个单元测试,其中设置模拟客户端,如下所示:
def setUp(self):
self.mock_client = mock.patch.object(module_name, 'ClientClassName', autospec=True).start()
然后在我的测试中我有一个伪造的返回值:
def myTest(self):
self.mock_client.my_method.return_value = ...
现在我想获取调用my_method
的参数,但是我一直在努力访问它们。 看来我不能这样做:
mock_args, mock_kwargs = self.mock_client.my_method.call_args
这让我回来了 首先为什么这不起作用? 我确实取得了一点进展,发现:
self.mock_client.method_calls[0]
会给我一个看起来像call().my_method(...the arguments)
的调用对象,但我已经尝试了几个小时来访问各个参数,但似乎无法做到。 我哪里错了?
调用参数只是通过订阅mock.call
对象来访问,即__getitem__
。
>>> from unittest.mock import MagicMock
>>> m = MagicMock()
>>> m(123, xyz="hello")
<MagicMock name='mock()' id='140736989479888'>
>>> m("another call")
<MagicMock name='mock()' id='140736989479888'>
>>> m.call_args_list
[call(123, xyz='hello'), call('another call')]
>>> m.call_args_list[0][0]
(123,)
>>> m.call_args_list[0][1]
{'xyz': 'hello'}
第 0 项将是 args 的元组,第 1 项将是 kwargs 的字典。 属性访问也可以工作,例如命名元组(第 0 项是属性“args”,第 1 项是属性“kwargs”)。 如果您只需要访问最近的通话,则可以使用call_args
而不是call_args_list
。
请注意,通常不需要直接访问调用 args项,您可以在测试中对另一个调用实例使用断言:
>>> from unittest.mock import call
>>> m(k=123)
<MagicMock name='mock()' id='140736989479888'>
>>> assert m.call_args == call(k=123) # pass
>>> assert m.call_args == call(k=124) # fail
AssertionError
或者更高级别,您可以直接在 mock 上使用m.assert_has_calls
。
模拟方法时,模拟调用是否有self
会受到 autospec 的影响:
>>> from unittest import mock
>>> class A(object):
... def f(self, *args, **kwargs):
... pass
...
>>> with mock.patch("__main__.A.f") as m:
... a = A()
... a.f('without autospec', n=1)
...
>>> m.call_args
call('without autospec', n=1)
>>> with mock.patch("__main__.A.f", autospec=True) as m:
... a = A()
... a.f('with autospec', n=2)
...
>>> m.call_args
call(<__main__.A object at 0x7fffe3d4e6a0>, 'with autospec', n=2)
这在此处的文档中有更详细的讨论。
除了 wim 的答案,您实际上可以深入挖掘这个参数,尽管有时您似乎找到了一个字符串而不是一个真实的对象。
要理解的要点是,当您遍历my_mock.call_args_list
时,您会得到unittest.mock._Call
类型的对象。 这些确实可以与您自己创建的call(...)
对象进行比较。 但这还不是全部。
unittest.mock._Call
本身是可迭代的,由 2 个元素组成:一个是另一个list
,另一个是dict
。 这些就是传递给模拟方法的*args
和**kwargs
。
您可以通过调用模拟对象上的 call_args_list 属性来获取参数
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.