Python - How to unmock/reset mock during testing?

golmschenk picture golmschenk · May 1, 2013 · Viewed 10.6k times · Source

I'm using nosetests and in two separate files I have two tests. Both run fine when run individually, but when run together, the mock from the first test messes up the results in the second test. How do I insure that all mocks/patches are reset after a test function is finished so that I get a clean test on every run?

If possible, explaining through my tests would be particularly appreciated. My first test looks like:

def test_list_all_channel(self):
    from notification.models import Channel, list_all_channel_names
    channel1 = Mock();
    channel2 = Mock();
    channel3 = Mock();
    channel1.name = "ch1"
    channel2.name = "ch2"
    channel3.name = "ch3"
    channel_list = [channel1, channel2, channel3]
    Channel.all = MagicMock()
    Channel.all.return_value = channel_list
    print Channel
    channel_name_list = list_all_channel_names()
    self.assertEqual("ch1", channel_name_list[0])
    self.assertEqual("ch2", channel_name_list[1])
    self.assertEqual("ch3", channel_name_list[2])

And my second test is:

def test_can_list_all_channels(self):
    add_channel_with_name("channel1")
    namelist = list_all_channel_names()
    self.assertEqual("channel1", namelist[0])

But the return value from Channel.all() is still set to the list from the first function so I get `"ch1" is not equal to "channel1". Any suggestions? Thank you much!

Answer

John Jiang picture John Jiang · May 1, 2013

Look up http://www.voidspace.org.uk/python/mock/patch.html

At the start of your test you initiate your patch and run

p = patch("Channel.all", new=MagicMock(return_value=channel_list))
p.start()

At the end:

p.stop()

This will ensure that your mocks are isolated to the test.