Karthikeyan Singaravelan <tir.kar...@gmail.com> added the comment: Using spec only checks for the attribute to be present and not the signature of the actual attribute being called. You might need autospec for this behavior. The below example to use create_autospec does the correct validation for mock_foo.func. There is an open issue to make spec also do signature validation but it could go into 3.9 only if accepted since it changes semantics : issue30587. Regarding the error message being cryptic there are other issues open on assertion error being displayed with actual and expected call list being same. I would propose closing this issue. Maybe the docs could be updated about this behavior to make sure using spec is more clear on the expected behavior.
https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock spec: This can be either a list of strings or an existing object (a class or instance) that acts as the specification for the mock object. If you pass in an object then a list of strings is formed by calling dir on the object (excluding unsupported magic attributes and methods). Accessing any attribute not in this list will raise an AttributeError. # bpo25312.py from unittest.mock import call, create_autospec, Mock import inspect class Foo: def __init__(self, val): pass def func(self): pass class FooMock(Mock): def _get_child_mock(self, **kwargs): return create_autospec(Foo) mock_foo = FooMock() print(inspect.signature(mock_foo.func)) # Signature is correct with create_autospec whereas with Mock(spec=Foo) it is (*args, **kwargs) mock_foo.func() # Raises TypeError with (val) being signature. mock_foo.func.assert_has_calls([call()]) ➜ cpython git:(master) ✗ ./python.exe bpo25312.py (val) Traceback (most recent call last): File "/Users/karthikeyansingaravelan/stuff/python/cpython/bpo25312.py", line 19, in <module> mock_foo.func() File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/unittest/mock.py", line 1027, in __call__ self._mock_check_sig(*args, **kwargs) File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/unittest/mock.py", line 119, in checksig sig.bind(*args, **kwargs) File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/inspect.py", line 3025, in bind return self._bind(args, kwargs) File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/inspect.py", line 2940, in _bind raise TypeError(msg) from None TypeError: missing a required argument: 'val' ---------- nosy: +cjw296, mariocj89 versions: +Python 3.7, Python 3.8, Python 3.9 -Python 3.4, Python 3.5, Python 3.6 _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue25312> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com