Find parent layout of child object, child layouts of parent objects

Is it possible to identify the parent MagicMock instance of the mock object instance of the child layout or the children of the parent layout example? For example, if I have the following code

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

How can I confirm later that the child is bullied by calling parent_mock ? How can I check which mock parent_mock objects parent_mock created?

Also, how could I tell if child_mock1 came from a call to parent_mock(a=1) , and child_mock2 came from a call to parent_mock(b='spam') ?

I understand that manually attaches layouts as attributes of other layouts , however, this requires a lot of settings, since you will need to make sure that the parent layout callbacks are explicitly set so that it returns the assigned child mocks, and therefore it does not scale long before several calls .

+4
source share
2 answers

How can I confirm later that the child is bullied by calling parent_mock ?

Well, there is an undocumented _mock_new_parent attribute that you could use like this:

 >>> 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 

... but it seems like the answer to all your other questions is "you can't."

I assume that you could subclass MagicMock track your children with something like this ...

 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 

... then you could do ...

 >>> 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
source

Caution!

26.4.2.1. Call

Layout objects are called. The call returns the value specified as the return_value attribute. The default return value is the new Mock object; it is created the first time the return value is accessed (either explicitly or by calling Mock), but it remains the same one that is returned each time .

If you want different calls to produce different results, you must give your layout the side_effect attribute. If mock.side_effect is a function, then mock(*args, **kwargs) will call mock.side_effect(*args, **kwargs) and return everything returned. You can make your own mock.side_effect keep track of which calls cause which values.

+1
source

Source: https://habr.com/ru/post/1482638/


All Articles