Skip to content
Advertisement

What does the instance argument in Python’s create_autospec do?

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.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement