3

The mock examples list this example:

>>> manager = MagicMock()
>>> with patch('mymodule.Class1') as MockClass1:
...     with patch('mymodule.Class2') as MockClass2:
...         manager.attach_mock(MockClass1, 'MockClass1')
...         manager.attach_mock(MockClass2, 'MockClass2')
...         MockClass1().foo()
...         MockClass2().bar()
...
<MagicMock name='mock.MockClass1().foo()' id='...'>
<MagicMock name='mock.MockClass2().bar()' id='...'>
>>> manager.mock_calls
[call.MockClass1(),
 call.MockClass1().foo(),
 call.MockClass2(),
 call.MockClass2().bar()]

I would like to accomplish the same thing, but with explicit start and stop calls on a patcher instead of the context manager, and it seems patcher.start() returns something which isn't really a mock in the same sense that contextualized one is, at least with respect to the ability to attach them to a parent mock:

>>> from mock import patch, Mock
>>> p = patch('requests.get', autospec=True)
>>> manager = Mock()
>>> manager.attach_mock(p.start(), 'requests_get')
>>> import requests
>>> requests.get('https://google.com')
<MagicMock name='get()' id='4472381392'>
>>> manager.mock_calls
[]
>>> p.stop()
>>> manager.mock_calls
[]

Am I missing something, or is this a bug, and what is the best way to go about mocking out several such calls and verifying that they are all made in the expected order?

  • Example is outdated: The docs linked have removed the example quoted in the question now. Closest analogy seems to be here, but it's not an exact match: https://docs.python.org/3/library/unittest.mock.html#attaching-mocks-as-attributes – wim May 29 '19 at 17:35

1 Answers1

1

Because of autospec=True and a function is being mocked out, patch will return a function, as well. In order to access the mock object, you can access patch(…).start().mock.