Павел Иванов
Павел Иванов

Reputation: 1913

How to mock an external api in django?

I'm trying to mock the "self.api.friends.get" method in VKAuth class:

import vk

class VKAuth(object):
    def __init__(self, access_token, user):
        self.session = vk.Session(access_token = access_token)
        self.api = vk.API(self.session)

    def follow(self):
        vk_friends = self.api.friends.get()

from the test module test_views.py:

from mock import patch
from ..auth_backends.vk_backend import VKAuth

class AddUsersToList(TestCase):
    @patch.object(VKAuth.api.friends, 'get')
    def test_auth_vk(self, mock_get):
         ... etc ...

And I get an error during testing:

AttributeError: <class 'accounts.auth_backends.vk_backend.VKAuth' doens't have the attribute 'api'

What am I doing wrong? How to get an access to this method in this class structure?

Upvotes: 1

Views: 1805

Answers (1)

Alex Morozov
Alex Morozov

Reputation: 5993

You're trying to mock a class itself, not it's instance. And the class doesn't have the api attribute, as it's created in your __init__(). Change your code to:

def test_auth_vk(self, mock_get):
    vk_auth = VKAuth(access_token, user)
    with mock.patch('vk_auth.api.friends') as friends_mock:
        friends_mock.get.return_value = None
        # Invoke the code that calls your api, passing the "vk_auth" variable as a backend.
        # ...
        friends_mock.mock.get.assert_called_with(your_arguments)

If you can't just pass an auth backend to your code, look up the place where it is instantiated and mock that place.

Upvotes: 2

Related Questions