from unittest import mock
class A:
def f(self): pass
m = mock.MagicMock(spec_set=A)
m.f.called_once() # I want this to fail
Out[42]: <MagicMock name='mock.f.called_once()' id='140326790593792'>
I have made a mistake in my unit test and called called_once
instead of assert_called_once
on a mocked method. The call results in a new MagicMock
instance, so the test was passing and not checking what I inteneded to check -- if the method was invoked. Is there a way to make mock fail if the method is not defined, when the mock is created from spec_set
? It's like I want spec_set
to be applied all the way down to the method mocks themselves.
Use create_autospec
:
from unittest import mock
class A:
def f(self): pass
m = mock.create_autospec(A)
m.f()
m.f.assert_called_once() # works OK
m.f.misstyped_called_once() # raises
Traceback (most recent call last):
File "/Users/ant/opt/miniconda3/envs/deeplearning/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3437, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-85-8fe8ab09b722>", line 7, in <module>
m.f.misstyped_called_once() # raises
File "/Users/ant/opt/miniconda3/envs/deeplearning/lib/python3.8/unittest/mock.py", line 637, in __getattr__
raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'misstyped_called_once'
It turns out there's a whole section devoted to this topic in the docs: https://docs.python.org/3/library/unittest.mock.html#autospeccing
Autospeccing is based on the existing spec feature of mock. It limits the api of mocks to the api of an original object (the spec), but it is recursive (implemented lazily) so that attributes of mocks only have the same api as the attributes of the spec.
EDIT
Looks there's a school of thought that avoids using the assert_called_xxx
in favour of explicit
assert mock_restart.call_count == 1
assert mock_restart.call_args == mock.call(“some argument”)
and another school that proposes a methodological solution -- if you do TDD, then your test must fail before you put in any implementation and this guards against the false positives.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.