Question

I try to patch the calc class in the code below. Inside the test code I want each 'Client' to be created with 'MockCalc' and not with 'Calc'. However this does not happen and the test return 12 and not 7. Calc is not replaced by MockCalc.

Note: 'test_mock_play' is the name of the python module (file) that holds this code.

Note: I prefer not to use decoration

import mock
import sys
import unittest

SEVEN = 7

class Calc:
    def __init__(self):
        print self.__class__
    def add(self,a,b):
        return a + b

class MockCalc:
    def __init__(self):
        print self.__class__
    def add(self,a,b):
        return SEVEN

class Client:
    def __init__(self):
        self.calc = Calc()
    def add(self,a,b):
        return self.calc.add(a,b)


class TestIt(unittest.TestCase):

    def setUp(self):
        self.mock_calc = mock.patch('test_mock_play.Calc',create=True, new=MockCalc)
        self.mock_calc.start()

    def tearDown(self):
        self.mock_calc.stop()

    def test_patch_class(self):
        '''Mocking the Calc and replace it with MockCalc.'''
        print " \npatch class "
        # client should be created with 'MockCalc'
        client = Client()
        # result should be 7
        result = client.add(4,8)
        print "1)" + str(result)
        self.assertEqual(result,SEVEN)


if __name__ == "__main__":
    unittest.main()
Was it helpful?

Solution

Workaround

Replace test_mock_play.Calc with __main__.Calc. But it is not recommended.

Recommended way

Split test_mock_play.py into two files: - Test code test_mock_play.py. - Implementation code: calc.py.

Import calc from test_mock_play. Replace references to Calc/Client to calc.Calc/calc.Client.

patch calc.Calc instead of test_mock_play.Calc.

calc.py

class Calc:
    def __init__(self):
        print self.__class__
    def add(self,a,b):
        return a + b

class Client:
    def __init__(self):
        self.calc = Calc()
    def add(self,a,b):
        return self.calc.add(a,b)

test_mock_play.py

import unittest
import mock
import calc

SEVEN = 7

class MockCalc:
    def __init__(self):
        print self.__class__
    def add(self,a,b):
        return SEVEN


class TestIt(unittest.TestCase):

    def setUp(self):
        self.mock_calc = mock.patch('calc.Calc',create=True, new=MockCalc)
        self.mock_calc.start()

    def tearDown(self):
        self.mock_calc.stop()

    def test_patch_class(self):
        '''Mocking the Calc and replace it with MockCalc.'''
        print " \npatch class "
        # client should be created with 'MockCalc'
        client = calc.Client()
        # result should be 7
        result = client.add(4,8)
        print "1)" + str(result)
        self.assertEqual(result,SEVEN)

if __name__ == "__main__":
    unittest.main()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top