I’m playing around with mock autospecs in Python. Here’s a basic test case where I’m autospecing the Django User
class using create_autospec.
from unittest.mock import create_autospec from django.contrib.auth.models import User def test_mock_spec(): user = create_autospec(User, spec_set=True, instance=True, username="batman") assert user.username == "batman" with pytest.raises(AttributeError): create_autospec(User, spec_set=True, x1=1) with pytest.raises(AttributeError): assert user.x2
The test passes when I set both instance=True
and instance=False
, so what exactly does this parameter do? What’s its purpose? I’ve seen multiple blog posts set it to True
(here and here) so I feel like it’s important.
The documentation says the following but it doesn’t make sense to me:
If a class is used as a spec then the return value of the mock (the instance of the class) will have the same spec. You can use a class as the spec for an instance object by passing instance=True. The returned mock will only be callable if instances of the mock are callable.
Advertisement
Answer
Consider mocking the int
class. int
is callable, like most classes, so a mock of the int
class should also be callable.
On the other hand, consider mocking an int
instance. Integers are not callable, so a mock of an integer should also not be callable.
The instance
argument lets you control which of these behaviors you get. create_autospec(int, instance=False)
returns a callable mock, while create_autospec(int, instance=True)
returns a non-callable mock. If you do
m1 = create_autospec(int, instance=False) m2 = create_autospec(int, instance=True) m1() m2()
only the m2()
line will raise an exception.