Search code examples
pythonmockingpython-unittestpython-mock

Python: mock patch class once for all test methods?


Consider this example:

module.py:

class LST:
    x = [1]


class T:
    def __init__(self, times):
        self.times = times

    def t1(self):
        return LST.x * self.times

    def t2(self):
        return LST.x * (self.times+1)

    def t3(self):
        return LST.x * (self.times+2)

test.py:

from mock import patch

import unittest
import module


@patch('module.LST')
class TestM(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        super(TestM, cls).setUpClass()
        cls.t = module.T(1)

    def test_01(self, LST):
        LST.x = [2]
        self.assertEqual([2], self.t.t1())

    def test_02(self, LST):
        LST.x = [2]
        self.assertEqual([2, 2], self.t.t2())

    def test_03(self, LST):
        LST.x = [2]
        self.assertEqual([2, 2, 2], self.t.t3())

I want to modify LST class with patch only once, because that same modification would be used for all tests.

Is it possible to modify it only once and then reuse it for all methods? So I would not need to repeat myself by doing LST.x = [2] on each method call?


Solution

  • How about:

    from mock import patch
    
    import unittest
    import module
    
    
    class TestM(unittest.TestCase):
    
        @classmethod
        def setUpClass(cls):
            super(TestM, cls).setUpClass()
            cls.t = module.T(1)
            cls.patcher = patch('module.LST')
            LST = cls.patcher.start()
            LST.x = [2]
    
        @classmethod
        def tearDownClass(cls):
            cls.patcher.stop()
    
        def test_01(self):
            self.assertEqual([2], self.t.t1())
    
        def test_02(self):
            self.assertEqual([2, 2], self.t.t2())
    
        def test_03(self):
            self.assertEqual([2, 2, 2], self.t.t3())
    

    The basic idea is that you can manually control that patching behavior.