When a unittest.mock.Mock
object has been called, I can check for the argument values with the exact signature of the call:
from unittest.mock import Mock
m = Mock() # creation of mock
m('foo', bar='baz') # call to the mock
m.assert_called_once_with('foo', bar='baz') # check call arguments
Checking for a different signature with the same values will fail. E.g., if we check with 'baz'
as a positional argument instead of a named argument, the assertion will fail:
m.assert_called_once_with('foo', 'baz')
# AssertionError: Expected call: mock('foo', 'baz')
# Actual call: mock('foo', bar='baz')
It has to. If the function replaced by m
was
def actual_fu(foo, bar):
# do something
then the calls would be equivalent, but if it was
def a_different_actual_fu(foo, *args, bar='some default'):
# do something
then the calls would not be equivalent. Mock
doesn't know the actual function's signature, so it can't rely on the equivalence we would have in the first case.
Is there a way of checking the call argument values that is agnostic about whether they were passed positionally or as keyword arguments, by letting the Mock (or an assertion helper function or similar) know about the actual function replaced by the mock?
The Mock
object can be made aware of the object it replaces (which can be a function or method) with the optional spec
argument or with autospeccing, but those serve a different purpose (limiting what calls to allow on the mock) and don't affect after-the-fact checking.