Since all members of a MagicMock
instance are also MagicMock
instances, I figured I could just mock the top-level object without having to mock every single member along a chain of calls. Then I could simply ask my original mock if any of its members have been called in a certain way, like with assert_called
. When I try this, the call list does indeed see the calls to children, but what is the assert method for testing them?
For example:
from unittest.mock import MagicMock
# Mock an object
foo = MagicMock()
# Try calling a child
foo.bar().baz()
# foo clearly registers the calls to its child...
print(foo.mock_calls)
# ...but how do I assert them?
foo.bar.assert_called()
foo.bar.baz.assert_called()
This doesn't work:
$ python assert_member_calls.py
[call.bar(), call.bar().baz()]
[call.bar(), call.bar().baz()]
Traceback (most recent call last):
File "/(...)/assert_member_calls.py", line 14, in <module>
foo.bar.baz.assert_called()
File "/(...)/python3.9/unittest/mock.py", line 876, in assert_called
raise AssertionError(msg)
AssertionError: Expected 'baz' to have been called.
I know that one solution is to basically create one mock for every attribute, so in addition to foo
, also explicitly mock bar
and baz
along with their return value. But that seems needlessly tedious. If foo
is a mock then bar
, bar()
, baz
and baz()
are already automatically mocks as well. I shouldn't have to reinstatiate a new mock and patch foo.bar.baz
(which was a mock to begin with) just so I can have a handle to do mock_baz.assert_called()
. To support my thinking, clearly the call list for foo
contains call.bar().baz()
-- is there not a method that can do assert that call.bar().baz() was called
?