Python 查找子对象的父模拟对象,父对象的子模拟对象
是否可以识别子模拟对象实例的父模拟对象实例,或父模拟对象实例的子模拟对象实例?例如,如果我有以下代码Python 查找子对象的父模拟对象,父对象的子模拟对象,python,unit-testing,mocking,Python,Unit Testing,Mocking,是否可以识别子模拟对象实例的父模拟对象实例,或父模拟对象实例的子模拟对象实例?例如,如果我有以下代码 >>> from unittest.mock import MagicMock >>> parent_mock = MagicMock() >>> child_mock1 = parent_mock(a=1) >>> child_mock2 = parent_mock(b='spam') 我以后如何确认子mock是从调用p
>>> from unittest.mock import MagicMock
>>> parent_mock = MagicMock()
>>> child_mock1 = parent_mock(a=1)
>>> child_mock2 = parent_mock(b='spam')
我以后如何确认子mock是从调用parent\u mock
生成的?如何检查生成了哪些模拟对象parent\u mock
另外,我如何区分child\u mock 1
专门来自调用parent\u mock(a=1)
,而child\u mock 2
来自调用parent\u mock(b='spam')
但是,我理解,它需要大量的设置,因为您需要明确定义父模拟的返回调用,以便它返回指定的子模拟,因此它不能扩展到几个调用之后
我以后如何确认子mock是从调用parent\u mock
生成的
嗯,有一个未记录的属性\u mock\u new\u 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
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
……但看起来你所有其他问题的答案都是“你不能”
我想你可以用类似这样的东西将MagicMock子类化来跟踪它的子类
>>> 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
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
>>parent\u mock=MyMock()
>>>子模拟1=父模拟(a=1)
>>>child_mock2=parent_mock(b='spam')
>>>家长们嘲笑孩子们
[((),{'a':1},),
((),{'b':'spam'},)]
>>>父项\u mock.\u子项[0][2]是子项\u mock 1
真的
>>>家长模仿。孩子[1][2]是孩子模仿2
真的
小心
模拟对象是可调用的。调用将返回设置为return_value属性的值。默认返回值是一个新的模拟对象;它是在第一次访问返回值时创建的(无论是显式的还是通过调用Mock),但它是存储的,每次都返回相同的值
如果您希望不同的调用给出不同的结果,那么您需要为您的mock提供一个属性。如果
mock.side\u effect
是一个函数,那么mock(*args,**kwargs)
将调用mock.side\u effect(*args,**kwargs)
并返回返回的任何内容。您可以自定义mock.side\u effect
跟踪什么调用产生了什么值。您可能根本不想做这样的事情。担心继承层次结构不是pythonic。你为什么想知道这些事情?很可能有另一种方法可以解决您的实际问题。@erikb85“父类”和“子类”的意思不是“超类”和“子类”<代码>模拟实例,调用时返回“child”模拟
实例(默认);创建另一个实例的Mock
实例称为“父实例”。该实例没有回答问题。:)我错过了那部分文档,谢谢!似乎@Aya的实现将MagicMock
子类化并覆盖\uuuu调用\uuuu
将实际返回不同的模拟实例。Aya的实现不起作用。它委托给MagicMock.\uuu调用\uuuu,它将始终返回相同的对象。换句话说,child\u mock1就是child\u mock2
。您的MyMock
仍然有child\u mock1就是child\u mock2
,因为您委托给MagicMock.\uu call\uu
,这不会为不同的调用创建不同的对象。你无法区分mock来自哪个调用。