How to mock nested / multiple layers of return objects in python
<p>I'm currently struggling to find a good way of mocking multiple layers / nested  return values. In other words, I want to return a magic mock that in turn returns a magic mock with it's own set return values. I'm finding this relatively cumbersome and am looking for a more elegant and maintainable solution.</p>

<p>I'm trying to test the following code efficiently. the URL returns a json string that needs further processing:</p>

<pre><code>import json
from urllib.request import url open

def load_json():
    # first return value
    response = urlopen("http://someurl.com/api/getjson")
    # in turn, contains two nested return values for read and decode
        response_dict = json.loads(response.read().decode('utf-8'))
</code></pre>

<p>This is how I've mocked this so far, which is extremely inelegant and makes maintenance complicated:</p>

<pre><code>class MyTestCase(TestCase):
    @patch('load_json_path.urlopen')
    def test_load_json(self, mock_urlopen):
        ### trying to simplify all of this
        # third nested return
        mock_decode = MagicMock(return_value='["myjsondata"]')
        # second nested return value
        mock_response = MagicMock()
        mock_response.read.return_value=mock_decode
        # first nested return value
        mock_urlopen.return_value = mock_response
        ### trying to simplify all of this            

        load_json()
</code></pre>

<p>In the end, all i'm trying to mock is the returned data from the decode function, that originates from the url open function.
This should be possible in one line or in a simpler way, using perhaps the <strong>enter</strong> methods.
Ideally the mock would look something like this in the test_load_json function:</p>

<pre><code>mock_urlopen.__enter__.loads.__enter__.decode.return_value = '["myjsondata"]'
</code></pre>

<p>Unfortunately, I can't seem to find anything useful in the mock documentation. Any help appreciated.</p>

<p>Turns out this is easily possible and documented. However, the naming is not straightforward and needed to know what one is looking for. The referred to mocking is chained calls, which are in fact documented in the mock library.</p>

<p>In this example, the mock_urlopen should look like this:</p>

<pre><code>    mock_urlopen.return_value.read.return_value.decode.return_value = '["myjsondata"]'
</code></pre>

<p>This works beautifully. For more details check out the python doc: <a href="https://docs.python.org/3/library/unittest.mock-examples.html#mocking-chained-calls" rel="nofollow">https://docs.python.org/3/library/unittest.mock-examples.html#mocking-chained-calls</a></p>

python nested mocking