Preventing typos with Python mock
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'
Much better.
Update: Paul Winkler points out that instead of passing spec=braintree.CreditCard
through you can pass autospec=True
. Good call.