Python mock call_args_list unpacking tuples for assertion on arguments
<p>I'm having some trouble dealing with the nested tuple which <code>Mock.call_args_list</code> returns.</p>

<pre><code>def test_foo(self):
    def foo(fn):
        fn('PASS and some other stuff')

    f = Mock()
    foo(f)
    foo(f)
    foo(f)

    for call in f.call_args_list:
        for args in call:
            for arg in args:
                self.assertTrue(arg.startswith('PASS'))
</code></pre>

<p>I would like to know if there is a better way to unpack that call_args_list on the mock object in order to make my assertion. This loop works, but it feels like there must be a more straight forward way.</p>

<p>I think that many of the difficulties here are wrapped up in the treatment of the "call" object.  It can be thought of as a tuple with 2 members <code>(args, kwargs)</code> and so it's frequently nice to unpack it:</p>

<pre><code>args, kwargs = call
</code></pre>

<p>Once it's unpacked, then you can make your assertions separately for args and kwargs (since one is a tuple and the other a dict)</p>

<pre><code>def test_foo(self):
    def foo(fn):
        fn('PASS and some other stuff')

    f = Mock()
    foo(f)
    foo(f)
    foo(f)

    for call in f.call_args_list:
        args, kwargs = call
        self.assertTrue(all(a.startswith('PASS') for a in args))
</code></pre>

<p>Note that sometimes the terseness isn't helpful (e.g. if there is an error):</p>

<pre><code>for call in f.call_args_list:
    args, kwargs = call
    for a in args:
        self.assertTrue(a.startswith('PASS'), msg="%s doesn't start with PASS" % a)
</code></pre>

python unit-testing python-unittest python-unittest.mock