aquavitae
aquavitae

Reputation: 19114

Patching a function using Mock

I have a test suite (using nose, not unittest), and I want to patch a function to return a specific sequence of values for every test in the test class. My first attempt, using a simplified example, was:

@patch('time.clock', MagicMock(side_effects=[1, 2]))
class Tests:
    def test_1(self):
        assert time.clock() == 1
        assert time.clock() == 2

    def test_2(self):
        assert time.clock() == 1
        assert time.clock() == 2

However, the MagicMock instance is only created once, so the second test fails when the side effects run out. I can patch each test method separately, but I don't really want to duplicate the patch decorator over all of them (there are a lot more tests than in this example!) The other way I could do it is to create the patch in the setup code like this:

class Tests:
    def setup(self):
        self.old_clock = time.clock
        time.clock = MagicMock(side_effects=[1, 2])

    def teardown(self):
        time.clock = self.old_clock

    def test_1(self):
        assert time.clock() == 1
        assert time.clock() == 2

    def test_2(self):
        assert time.clock() == 1
        assert time.clock() == 2

But saving and restoring the original function definition seems like something that Mock should be able to do automatically. Is there another method of doing this that I'm missing? Or is my last example the best way of doing this?

Upvotes: 5

Views: 1131

Answers (2)

Falc
Falc

Reputation: 371

You should just apply the patch to every test, instead of applying it to the class:

class Tests:
    @patch('time.clock', MagicMock(side_effects=[1, 2]))
    def test_1(self):
        assert time.clock() == 1
        assert time.clock() == 2

    @patch('time.clock', MagicMock(side_effects=[1, 2]))
    def test_2(self):
        assert time.clock() == 1
        assert time.clock() == 2

Upvotes: 1

Nasgar
Nasgar

Reputation: 951

a = (x for x in [1,2])

x = lambda : next(a)

x()

Out: 1

x()

Out: 2

Put your answers into a's list. Change X for your desired name.

Upvotes: 2

Related Questions