Search code examples
pythonpython-unittestpython-mock

How to patch a class in python unit test and get a handle on patched object's return value


I am testing a class's method in Python 2.7 using Mock 2.0.0 Library

Here is how the method under test looks like:

from sklearn.externals import joblib

    class ClassUnderTest():

        def MethodUnderTest(self, path, myDict):

            newDict= {}

            for key, val in myDict.iteritems():
                retVal= (joblib.load(path + val))
                newDict[key] = retVal

            return newDict

Now, my intention is to test MethodUnderTest but mock joblib.load and not call it in reality. So, to achieve this, I use the @patch decorator available in Mock library. My test looks as follows:

import unittest from mock import MagicMock, patch from sklearn.externals import joblib import ClassUnderTest

class TestClass(unittest.TestCase):

    @patch('ClassUnderTest.joblib')
    def test_MethodUnderTest(self, mockJoblibLoad):

        dict = {"v1": "p1.pkl"}        
        retVal = ClassUnderTest.MethodUnderTest("whateverpath", dict)

Now if I have to assert on retVal's keys and values against something, that something is based on what the mocked return value of joblib.load is. If I knew that value somehow then, I would be able to know what MethodUnderTest returns.

The problem here is that I don't know what that mocked value of joblib.load is when it is mocked using @patch decorator.

Does someone know how to get around this problem ? Or if there is a better way to mock python libraries like joblib and their methods like load and get a handle of that mock object ?


Solution

  • class TestClass(unittest.TestCase):
    
        @patch('path.to.module.joblib.load')  # You path is probably wrong here
        def test_MethodUnderTest(self, mockJoblibLoad):
            # Set the side_effect if you want to return different things on 
            # each iteration e.g. mockJoblib.side_effect = [...]
            mockJoblibLoad.return_value = ...  
            test_dict = {"v1": "p1.pkl"}        
            expect = {"v1": mockJoblibLoad.return_value}
            actual = ClassUnderTest.MethodUnderTest("whateverpath", dict)
            self.assertEqual(expect, actual)