6

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?

Andrius
  • 19,658
  • 37
  • 143
  • 243
  • would you also consider an answer that uses pytest instead of unittest? – Arne Aug 22 '19 at 06:52
  • @Arne no, it would need to be unittest. I'm using framework that uses unittest by default, so it would be inconvenience to change it. – Andrius Aug 22 '19 at 07:06

1 Answers1

8

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.

Sraw
  • 18,892
  • 11
  • 54
  • 87
  • This is great solution. Just what I needed, thanks. – Andrius Aug 22 '19 at 07:05
  • 1
    For completeness, I would suggest adding `super` on `tearDownClass`, cause it can cause unintended consequences in same cases if you override `tearDownClass` without calling super. – Andrius Aug 22 '19 at 14:35