[Django]-How to mock class attribute instantiated in __init__?

6👍

You are patching the wrong thing. In VKAuth:

self.api = vk.API(self.session)

add api attribute to VKAuth self object. When you call

patch.object(accounts.auth_backends.vk_backend.VKAuth, 'api')

you are patching the api static attribute of VKAuth class and not the object attribute.

You should patch vk.API instead.

with patch('vk.API', autospec=True) as mock_api:
    response = self.client.post(reverse('auth-social', kwargs=dict(backend='vk')), dict(access_token=auth_token), follow=True)

Notes :

  1. Use patch.object only if you really know why you need it instead simple patch.
  2. autospec=True is not mandatory but I strongly encourage to use it.
  3. In the patch context self.api will be equal to mock_api.return_value because call vk.API(self.session) is like call mock_api(); in other words mock_api is the mock object used to replace the vk.API reference.
  4. Take a look to where to patch, you can find it very useful.

Now if you want fill your mock_api.return_value by some behavior you can configure it in with context:

with patch('vk.API', autospec=True) as mock_api:
    m_api = mock_api.return_value
    m_api.friends.return_value = None
    m_api.friends.get.return_value = vk_ids
    .... Your test

Leave a comment