When using unittest.mock.patch, why is autospec not True by default?

Viewed 25523

When you patch a function using mock, you have the option to specify autospec as True:

If you set autospec=True then the mock with be created with a spec from the object being replaced. All attributes of the mock will also have the spec of the corresponding attribute of the object being replaced. Methods and functions being mocked will have their arguments checked and will raise a TypeError if they are called with the wrong signature.

(http://www.voidspace.org.uk/python/mock/patch.html)

I'm wondering why this isn't the default behaviour? Surely we would almost always want to catch passing incorrect parameters to any function we patch?

3 Answers

Answering my own question many years later - another reason is speed.

Depending on how complex your object is, it can be that using autospec can slow your test down significantly. I've found this particularly when patching Django models.

The action of autospeccing itself can execute code, for example via the invocation of descriptors.

>>> class A: 
...     @property 
...     def foo(self): 
...         print("rm -rf /") 
... 
>>> a = A() 
>>> with mock.patch("__main__.a", autospec=False) as m: 
...     pass 
... 
>>> with mock.patch("__main__.a", autospec=True) as m: 
...     pass 
... 
rm -rf /

Therefore, this is a problematic feature to enable by default and is opt-in only.

Related