Python mock is pretty cool, but there's been a recurring problem for me with mock in that if you access any property on a Mock it returns a method which is truthy. This means simple typos can exist in your testing.
As an example, in this library, there's a method
from_nonce. If you just mock the object, then you can typo the method and it continues like normal:
>>> with mock.patch('braintree.CreditCard') as mocked: ... assert mocked.from_none ...
This has happened to me and I didn't notice when I'd typo'd a mock call, like
is_called. The test were wrong, but passed quite happily.
The better way is to pass the object to the Mock call as
spec. Then only methods on the object can be called, for example:
>>> with mock.patch('braintree.CreditCard', spec=braintree.CreditCard) as mocked: ... assert mocked.from_none ... Traceback (most recent call last): [..snip] File "/Users/andy/.virtualenvs/solitude/lib/python2.7/site-packages/mock.py", line 658, in __getattr__ raise AttributeError("Mock object has no attribute %r" % name) AttributeError: Mock object has no attribute 'from_none'
Update: Paul Winkler points out that instead of passing
spec=braintree.CreditCard through you can pass
autospec=True. Good call.