是否可以识别子模拟对象实例的父MagicMock
模拟对象实例,或父模拟对象实例的子实例?例如,如果我有以下代码
>>> from unittest.mock import MagicMock
>>> parent_mock = MagicMock()
>>> child_mock1 = parent_mock(a=1)
>>> child_mock2 = parent_mock(b='spam')
我怎么能在以后确认孩子的嘲笑是通过调用parent_mock
而产生的?我怎样才能检查哪些模拟对象parent_mock
生成了?
此外,我如何区分child_mock1
来自电话parent_mock(a=1)
,而child_mock2
来自电话parent_mock(b='spam')
?
我理解一个人可以manually attach mocks as attributes of other mocks,但是,它需要大量的设置,你需要确保明确定义父模拟的返回调用,以便它返回指定的子模拟,并且所以它不能通过几次调用很好地扩展。
答案 0 :(得分:1)
我怎么能在稍后确认通过调用
parent_mock
产生的儿童嘲笑?
嗯,有一个未记录的属性_mock_new_parent
,您可以像这样使用...
>>> from unittest.mock import MagicMock
>>> parent_mock = MagicMock()
>>> child_mock1 = parent_mock(a=1)
>>> child_mock2 = parent_mock(b='spam')
>>> child_mock1._mock_new_parent is parent_mock
True
>>> child_mock2._mock_new_parent is parent_mock
True
...但看起来你所有其他问题的答案都是“你不能”。
我想你可以将MagicMock
子类化为跟踪它的孩子...
class MyMock(MagicMock):
def __init__(self, *args, **kwargs):
MagicMock.__init__(self, *args, **kwargs)
self._kids = []
def __call__(self, *args, **kwargs):
result = MagicMock.__call__(self, *args, **kwargs)
self._kids.append((args, kwargs, result))
return result
......那你就可以......
>>> parent_mock = MyMock()
>>> child_mock1 = parent_mock(a=1)
>>> child_mock2 = parent_mock(b='spam')
>>> parent_mock._kids
[((), {'a': 1}, <MyMock name='mock()' id='140358357513616'>),
((), {'b': 'spam'}, <MyMock name='mock()' id='140358357513616'>)]
>>> parent_mock._kids[0][2] is child_mock1
True
>>> parent_mock._kids[1][2] is child_mock2
True
答案 1 :(得分:1)
小心!
模拟对象是可调用的。该调用将返回设置为return_value属性的值。默认返回值是一个新的Mock对象;它是在第一次访问返回值时创建的(显式或通过调用Mock) - 但它存储并且每次都返回相同的。
如果您希望不同的调用提供不同的结果,您需要为模拟提供side_effect
属性。如果mock.side_effect
是一个函数,那么mock(*args, **kwargs)
将调用mock.side_effect(*args, **kwargs)
并返回返回的内容。您可以让自定义mock.side_effect
跟踪哪些调用产生的值。