我不确定在python类的方法上构建独立单元测试的最佳方法是什么。这是一个简单的例子:
class MyClass(object):
def __init__(self, data):
self.data = data
def myMethod(self):
#do something
return True
我正在构建像这样的单元测试:
class TestMyClass(unittest.TestCase):
def test_init(self):
mydata = mock.Mock()
c = MyClass(mydata)
self.assertEqual(c.data, mydata)
def test_myMethod(self):
mydata = mock.Mock()
c = MyClass(mydata)
self.assertTrue(c.myMethod())
好的,这非常简单......但重点是:test_myMethod()
取决于__init__
,因为我必须实例化对象本身:它并不是真正孤立的。解决这个问题的唯一方法就是模拟对象本身...但是如何在模拟对象上测试一个真实的方法呢?
我知道在现实世界中,完全隔离是不可能的,但我很想知道是否有更好的方法。
答案 0 :(得分:2)
归结为您要测试的内容以及粒度。例如,c.data
等于您在上一行中刚刚分配的数据实际测试的断言究竟是什么?它测试了一行实用代码,并测试了一个相当不重要的实现细节。这可能太精细了,不会打扰。
您希望确保您的对象的整体行为。这意味着你想测试你可以实例化它,然后断言
您的测试应该关注对象行为,而不是测试实现细节。编写测试,以便在不破坏测试的情况下,以不同的方式插入实现相同行为的替代对象。您正在编写该类以完成某些指定的任务;测试您的实现是否可以完成这些任务,而不是如何完成任务。
Exemptigratia:
def test_worksWithDataA(self):
c = MyClass({'some': 'data'})
self.assertTrue(c.myMethod())
def test_worksWithDataB(self):
c = MyClass({'other': 'data'})
self.assertFalse(c.myMethod())
def test_rejectsDataC(self):
with self.assertRaises(SomeException):
MyClass(None)
如果需要传递依赖项,则只需要模拟某些内容,但为了测试,该依赖项太复杂而无法实例化。只要您的数据只是dict
,就没有必要嘲笑它。如果您的数据本身就是一个复杂的类型,那么您可能想要模拟它以便测试MyClass
,而不必纠结于必须同时测试其他类。再次模拟时,模拟该类的预期行为;根据经验,你声称你的类使用单元测试的所有行为都可以在别处嘲笑。