How to assert call order and parameters when mocking multiple calls to the same method?
<p>I have multiple calls to the same mock and I want to check each calls parameters and order in which it was called.</p>

<p>E.g. if I needed to check just the last call, I would use this:</p>

<pre><code>mock.assert_called_once_with(
    'GET',
    'https://www.foobar.com',
    params=OrderedDict([
        ('email', 'email'),
    ]),
    headers=None, 
    data=None)
</code></pre>

<p>However I want to do this for each call.</p>

<p>I've managed to do that, like this:</p>

<p>mycode.py</p>

<pre><code>from requests import Session

class Foo(object):

    def req(method, url, data, params=None, headers=None):
        self.session = Session()
        r = self.session.request(method, url, data=data, params=params, headers=headers)
        return r
</code></pre>

<p>test_mycode.py</p>

<pre><code>@patch('myapp.mycode.Session')
def test_foobar(self, Session):
    # Set mock.
    self.request_mock = Session.return_value.request
    self.request_mock.return_value = MagicMock()

    data = {'foo': 'bar'}
    f = Foo()
    f.req('POST', 'https://www.foobar.com/', data=data)
    f.req('GET', 'https://www.foobar.com/', data=None)


    self.assertEqual(self.request_mock.call_count, 2)
    call1 = self.request_mock._mock_call_args_list[0]
    call2 = self.request_mock._mock_call_args_list[1]

    call_params = (
        ('POST', 'https://www.foobar.com'),
        {
            'headers': None,
            'allow_redirects': False,
            'params': None,
            'data': json.dumps(data)
        }
    )
    self.assertEqual(tuple(call1), call_params)

    call_params = (
        ('GET', 'https://www.foobar.com'),
        {
            'headers': None,
            'allow_redirects': False,
            'params': None,
            'data': None
        }
    )
    self.assertEqual(tuple(call2), call_params)
</code></pre>

<p>This works, but I'm a little concerned about my assertEqual methods on call parameters. I feel like there's a better way of doing this. I'm still fairly new to mocking so any suggestions would be appreciated.</p>

<p>You probably want to use the <a href="https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.assert_has_calls" rel="nofollow"><code>Mock.assert_has_calls</code></a> method.</p>

<pre><code>self.assertEqual(self.request_mock.call_count, 2)
self.request_mock.assert_has_calls([
    mock.call(
        'POST',
        'https://www.foobar.com',
        headers=None,
        allow_redirects=False,
        params=None,
        data=json.dumps(data)),
    mock.call(
        'GET',
        'https://www.foobar.com',
        headers=None,
        allow_redirects=False,
        params=None,
        data=None)
])
</code></pre>

<p>By default, <code>assert_has_calls</code> will check that the calls happen in the proper order.  If you don't care about the order, you can use the <code>any_order</code> keyword argument (set to <code>True</code>).</p>

python unit-testing mocking