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>A nicer way might be to build up the expected calls your self then use a direct assertion:</p>

<pre><code>&gt;&gt;&gt; from mock import call, Mock
&gt;&gt;&gt; f = Mock()
&gt;&gt;&gt; f('first call')
&lt;Mock name='mock()' id='31270416'&gt;
&gt;&gt;&gt; f('second call')
&lt;Mock name='mock()' id='31270416'&gt;
&gt;&gt;&gt; expected_calls = [call(s + ' call') for s in ('first', 'second')]
&gt;&gt;&gt; f.assert_has_calls(expected_calls)
</code></pre>

<p>Note that the calls must be sequential, if you don't want that then override the <code>any_order</code> kwarg to the assertion.  </p>

<p>Also note that it's permitted for there to be extra calls before or after the
specified calls.  If you don't want that, you'll need to add another assertion:</p>

<pre><code>&gt;&gt;&gt; assert f.call_count == len(expected_calls)
</code></pre>

<hr>

<p>Addressing the comment of mgilson, here's an example of creating a dummy object that you can use for wildcard equality comparisons:</p>

<pre><code>&gt;&gt;&gt; class AnySuffix(object):
...     def __eq__(self, other):
...         try:
...             return other.startswith('PASS')
...         except Exception:
...             return False
...        
&gt;&gt;&gt; f = Mock()
&gt;&gt;&gt; f('PASS and some other stuff')
&lt;Mock name='mock()' id='28717456'&gt;
&gt;&gt;&gt; f('PASS more stuff')
&lt;Mock name='mock()' id='28717456'&gt;
&gt;&gt;&gt; f("PASS blah blah don't care")
&lt;Mock name='mock()' id='28717456'&gt;
&gt;&gt;&gt; expected_calls = [call(AnySuffix())]*3
&gt;&gt;&gt; f.assert_has_calls(expected_calls)
</code></pre>

<p>And an example of the failure mode:</p>

<pre><code>&gt;&gt;&gt; Mock().assert_has_calls(expected_calls)
AssertionError: Calls not found.
Expected: [call(&lt;__main__.AnySuffix object at 0x1f6d750&gt;),
 call(&lt;__main__.AnySuffix object at 0x1f6d750&gt;),
 call(&lt;__main__.AnySuffix object at 0x1f6d750&gt;)]
Actual: []
</code></pre>

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