4

是否可以识别子MagicMock模拟对象实例的父模拟对象实例或父模拟对象实例的子对象?例如,如果我有以下代码

>>> from unittest.mock import MagicMock
>>> parent_mock = MagicMock()
>>> child_mock1 = parent_mock(a=1)
>>> child_mock2 = parent_mock(b='spam')

我以后如何确认孩子嘲笑是从 call 中产生的parent_mock?我如何检查parent_mock生成了哪些模拟对象?

另外,我怎么能区分child_mock1具体来自 call parent_mock(a=1),而child_mock2来自 call parent_mock(b='spam')

我知道可以手动将模拟附加为其他模拟的属性,但是,它需要大量设置,因为您需要确保明确定义父模拟的返回调用,以便它返回指定的子模拟,并且所以它不能很好地扩展过去的几个电话。

4

2 回答 2

2

那里小心!

26.4.2.1。打电话

模拟对象是可调用的。该调用将返回设置为 return_value 属性的值。默认返回值是一个新的 Mock 对象;它是在第一次访问返回值时创建的(显式地或通过调用 Mock) - 但它被存储并且每次都返回相同的值。

如果你想要不同的调用来给出不同的结果,你会想要给你的模拟一个side_effect属性。如果mock.side_effect是一个函数,那么mock(*args, **kwargs)将调用mock.side_effect(*args, **kwargs)并返回返回的任何内容。您可以让您的自定义mock.side_effect跟踪哪些调用产生了哪些值。

于 2013-06-07T04:09:55.067 回答
2

我以后如何确认孩子嘲笑是从 call 中产生的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
于 2013-06-04T15:57:29.190 回答