Search code examples
pythondjangounit-testingmockingpython-mock

How to add the fictive method


Inside of the class, I use VK API. During the test, I use MagicMock to mock authorization in the API this class uses:

    vk.Session = MagicMock(name='session', return_value=None)
    vk.API = MagicMock(name='api')
    mock_vk_values = [{'uid': user.vk_uid}]
    vk.API.users.get = MagicMock(name='uid', return_value=mock_vk_values)

But, inside of the class, I use this API to get the user's uid:

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

      def authenticate(self):
          try:
              vk_uid = self.api.users.get()[0]['uid']

On this place it gets an error:

*** AttributeError: 'NoneType' object has no attribute 'users'

How to mock this stuff right?

Thank you!


Solution

  • Try this:

    vk.Session = MagicMock(name='session', return_value=None)
    mock_vk_values = [{'uid': user.vk_uid}]
    # create an explicit mock for the users attribute
    users_mock = MagicMock(name='users')
    users_mock.get = MagicMock(name='uid', return_value=mock_vk_values)
    # create a mock for the api
    api_mock = MagicMock(name='api', users=users_mock)
    # this is where a lot of people get mocking wrong -
    # mistaking the mock of a constructor with the object returned/created
    vk.API = MagicMock(return_value=api_mock)