[TIP] Is this a bug in unittest.mock, or am I missing something?

John W jwdevel at gmail.com
Thu Feb 16 16:38:04 PST 2017


To take your approach, and do what (I think) I'm trying to do, I'd write:

    from unittest import mock
    def test_calls_match_2():
        """
        Calls on a Mock match expectation
        """
        constructor = mock.Mock()
        instance = constructor()
        instance.my_method(123)

        constructor.assert_has_calls([mock.call(), mock.call().my_method(123)])

That passes just fine for me, and seems reasonable.

I think the reason you had "call()" vs "call" was that "m" in your
example had "my_method" called on it directly, rather than calling it
on the result of the initial call to "m()". That is - calling
my_method on the constructor, rather than the instance.

So that all seems fine to me, and seems to work as expected.

But then, when mock.patch and autospec get involved, as in my original
example, it all seems to go south...

-John

On 2/16/17, James Cooke <me at jamescooke.info> wrote:
> Hi John,
>
>
>
> This is interesting and thanks for sharing it. Running python 3.5.2, I
> firstly simplified your example and got a slightly different exception:
>
>
> from unittest import mock
>
>
>
>
>
> def test_calls_match():
>
>     """
>
>     Calls on a Mock match expectation
>
>     """
>
>     m = mock.Mock()
>
>     m()
>
>     m.my_method(123)
>
>
>
>     m.assert_has_calls([mock.call(), mock.call().my_method(123)])
>
>
>
> The exception is slightly different for me:
>
>
>
> E               AssertionError: Calls not found.
>
> E               Expected: [call(), call().my_method(123)]
>
> E               Actual: [call(), call.my_method(123)]
>
>
>
> When I remove the parentheses after the second `call`, then everything
> works for me, and the test passes.
>
>
>     m.assert_has_calls([mock.call(), mock.call.my_method(123)])
>
>
>
> My assumption is that MagicMock will operate like Mock and that your
> MockFoo is a MagicMock, so could you try the `mock.call.my_method` on
> Python 3.4?
>
>
> I'm interested to hear how that works for you.
>
>
>
> Cheers,
>
>
>
> James
>
>
>
>
>
>
>
>
>
> On Thu, 16 Feb 2017, at 07:06 PM, John W wrote:
>
>> They seem to be the same types.
>
>>
>
>> I added these prints:
>
>>
>
>>         print("type of call():", type(call()))
>
>>         print("type of call().my_method(123):",
>
>>         type(call().my_method(123)))
>
>>         for c in MockFoo.mock_calls:
>
>>             print("type of mock call '{}': {}".format(c, type(c)))
>
>>
>
>> And output is:
>
>>
>
>>     type of call(): <class 'unittest.mock._Call'>
>
>>     type of call().my_method(123): <class 'unittest.mock._Call'>
>
>>     type of mock call 'call()': <class 'unittest.mock._Call'>
>
>>     type of mock call 'call().my_method(123)': <class
>
>>     'unittest.mock._Call'>
>
>>
>
>>
>
>> Thanks for the suggestion though.
>
>> I've been getting crickets from every place I've asked this
>> question (:
>>
>
>> -John
>
>>
>
>> _______________________________________________
>
>> testing-in-python mailing list
>
>> testing-in-python at lists.idyll.org
>
>> http://lists.idyll.org/listinfo/testing-in-python
>
>
>
>
>
> --
>
> James Cooke
>
> Backend software developer
>
> CV PDF: http://jamescooke.info/docs/james_cooke_cv.pdf
>
> Website: http://jamescooke.info/
>



More information about the testing-in-python mailing list