Luca
Luca

Reputation: 10996

python unittest sharing object instances between tests

I am writing some unit tests in Python and it seems that my tests are somehow sharing the objects between the test functions which seem weird to be. So, I have something like:

import unittest 

class TestMyMethods(unittest.TestCase):

    def test_create(self):
        c = MyClass()
        c.create_customer('Luca')
        self.assertEqual(len(c.data), 1)

    def test_connect(self):
        c = MyClass()
        c.connect_customer('Angela', 'Peter')
        self.assertEqual(len(c.data), 2)

If I comment any of the test out, the other one passes but the two together fail. On examination, it seems that the c object persists between the two test functions but why should this be? In the function new instances are created. Is this some "feature" from the unittest framework?

from collections import defaultdict
class MyClass(object):
    def __init__(self):
        self.data = defaultdict()

    def create_customer(self, cust):
        if cust not in self.data:
            self.data[cust] = list()

    def connect_customer(self, a, b):
        if a not in self.data:
            self.data[a] = list()

        if b not in self.data:
            self.data[b] = list()

        self.data[a].append(b)

OK, this is weird. I looked at the history and before I had this:

class MyClass(object):
    def __init__(self, data=defaultdict()):
        self.data = data

And the tests were not working when I was initializing like this. It actually works now. I must have deleted this an not kept track.

Does anyone know why this does not work? but doing self.data = defaultdict() is fine.

Upvotes: 5

Views: 3115

Answers (1)

Josh J
Josh J

Reputation: 6893

It is because you were using a mutable object as the default value of a method parameter. The object is created once and then shared among all calls of that method, regardless of which value self contains.

https://python-guide.readthedocs.io/en/latest/writing/gotchas/

Upvotes: 6

Related Questions