Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python mockito - Mocking a class which is being instantiated from the testable function

I am bit lost while writing the test case for UserCompanyRateLimitValidation class. I am finding difficulty in mocking the class which is being instantiated from inside this class.

class UserCompanyRateLimitValidation:
    def __init__(self, user_public_key):
        self.adapter = UserAdapter(user_public_key)
        container = self.adapter.get_user_company_rate_limit()
        super(UserCompanyRateLimitValidation, self).__init__(container,\
                                            UserCompanyRateLimitValidation.TYPE)

I have to test this class. I have written test case something like this. I have tried to mock the UserAdapter class but I am not able to do so completely.

def test_case_1():
   self.user_public_key = 'TEST_USER_PUBLIC_KEY_XXXXXX1234567890XXXXX'
   UserAdapter_mock = mock(UserAdapter)
   when(UserAdapter_mock).get_user_company_rate_limit().\
                                          thenReturn(get_fake_container_object())

   self.test_obj = UserCompanyRateLimitValidation(self.user_public_key)

Here if you see I have mocked get_user_company_rate_limit() call from the testable function, container = self.adapter.get_user_company_rate_limit() but I am still not able to figure out the way in which I can mock this call,

 self.adapter = UserAdapter(user_public_key)
like image 638
Bhupesh Pant Avatar asked Feb 27 '14 09:02

Bhupesh Pant


People also ask

Can Mockito mock a class?

Mockito mocking framework provides different ways to mock a class. Let's look at different methods through which we can mock a class and stub its behaviors.

What is mocking in Mockito?

The Mockito. mock() method allows us to create a mock object of a class or an interface. We can then use the mock to stub return values for its methods and verify if they were called.

How do you mock a class in Unittest Python?

To mock objects, you use the unittest. mock module. The unittest. mock module provides the Mock class that allows you to mock other objects.


2 Answers

It is quite simple if you know the trick.

Creating an object in Python is very much like a function call to the class object. UserCompanyRateLimitValidation is 'invoking' UserAdapter(user_public_key). You want to stub the return value of that 'call' to return UserAdapter_mock.

You can stub this like you would stub a function in a module. The line you're missing is:

when(module_declaring_UserAdapter)\
    .UserAdapter(self.user_public_key)\
    .thenReturn(UserAdapter_mock)

After that, calling module_declaring_UserAdapter.UserAdapter(self.user_public_key) will return UserAdapter_mock.

Here's the link to the section in the manual: https://code.google.com/p/mockito-python/wiki/Stubbing#Modules

You have to be careful to choose the right module_declaring_UserAdapter, due to the way the from ... import ... statement works. From your code, I'd say you have to pick the module in which UserCompanyRateLimitValidation is declared.

like image 69
Stefan Avatar answered Nov 04 '22 17:11

Stefan


Here is another way of looking at it. Say I have this code in which I would like to mock MyClass:

from some.module import MyClass

class AnotherClass:

    def __init__(self):
        self.my_class = MyClass()

One would typically call the imports as shown above. With some slight modification of the import, we can get it into a state where MyClass it can be mocked using mockito:

from some import module

class AnotherClass:

    def __init__(self):
        self.my_class = module.MyClass()

Then the mocking would work like so:

from some import module

when(module).MyClass().thenReturn(mock())
like image 20
Daniel Holmes Avatar answered Nov 04 '22 17:11

Daniel Holmes