Reputation: 7796
Let's say I have a module named foo
with a class Bar
. Bar
has a classwide counter attribute that allows me to track the order which instances were created. foo
looks like this:
from itertools import count
class Bar:
class_count = count(0)
def __init__(self):
self.id = self.class_count.next()
Now I have a test file where I am testing the various functionalities of Bar
. I am unsure of how to test this id
attribute, because the other unittests are creating instances of Bar
and so I don't know what the given id of a Bar
instance should be. Furthermore, this behavior of my class means that my unittests are independent of each other, which is undesirable. How should I structure my unittests so the tests are independent of each other?
Upvotes: 1
Views: 268
Reputation: 1884
I would stub out Bar to bypass the constructor.
class BarStub(Bar):
def __init__(self):
self.class_count = None
self.id = None
Now you can test like this:
class TestBar(...):
def setUp(...)
...
self.bar = BarStub()
def test_foo_should_blah_when_blah(self):
with mock.patch.object(self.bar, 'count_class', side_effect=[...]) as mock_count:
actual = self.bar.unit_under_test(...)
mock_count.assert_called_with([...])
Upvotes: 0
Reputation: 152657
You could use setUp
to safe the current count and then temporarily reset the count. Then with tearDown
you restore the original state again:
from itertools import count
import unittest
class Bar:
class_count = count(0)
def __init__(self):
self.id = next(self.class_count)
class TestBar(unittest.TestCase):
def setUp(self):
self.nxtcount = next(Bar.class_count) # safe current state
Bar.class_count = count(0) # reset to 0
def tearDown(self):
Bar.class_count = count(self.nxtcount) # reset to old state
def teststh1(self):
x = Bar()
self.assertEqual(x.id, 0)
def teststh2(self):
x1 = Bar()
x2 = Bar()
x3 = Bar()
self.assertEqual(x1.id, 0)
self.assertEqual(x2.id, 1)
self.assertEqual(x3.id, 2)
This makes sure every test method will start with a Bar.class_count
of 0.
Upvotes: 1