vendredi 27 mai 2016

Mocking side_effect while autospeccing gives the function additional argument

So the example code is very basic:

@mock.patch.object(BookForm, 'is_valid')
def test_edit(self, mocked_is_valid):
    create_superuser()
    self.client.login(username="test", password="test")

    book = Book()
    book.save()

    mocked_is_valid.side_effect = lambda: True

    self.client.post(reverse('edit', args=[book.pk]), {})

This works well. But adding autospec keyword to the mock:

@mock.patch.object(BookForm, 'is_valid', autospec=True)

causes additional argument to be passed to the side_effect callable, which obviously results in error:

TypeError: <lambda>() takes 0 positional arguments but 1 was given

What I don't uderstand, is why autospeccing gives additional argument. I've read the docs, but still can't find the explanation of this behaviour.

Theoretically, it's written that

In addition mocked functions / methods have the same call signature as the original so they raise a TypeError if they are called incorrectly.

so it'd be okay (is_valid has self argument, which is probably what is being passed here), but on the other hand it's also written about side_effect that

The function is called with the same arguments as the mock, and unless it returns DEFAULT, the return value of this function is used as the return value.

So as far as I understand, side_effect should be called with the self argument even without autospeccing. But it is not.

is called with the same arguments as the mock

if form.is_valid():  # the mock is_valid is called with the self argument, isn't it?

So if someone could explain it to me, preferably quoting the docs, I'd be thankful.

Aucun commentaire:

Enregistrer un commentaire