Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I attach the return value of mock.patch(...).start() to a parent mock?

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?

like image 864
Andrey Fedorov Avatar asked Dec 20 '25 17:12

Andrey Fedorov


1 Answers

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.

like image 50
Andrey Fedorov Avatar answered Dec 23 '25 08:12

Andrey Fedorov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!