单元测试:测试父对象方法是否有意义?

时间:2011-04-19 20:03:57

标签: python django unit-testing tdd

假设我使用的是一个名为Animal的类。

class Animal(object):
    def speak(self):
        logging.info(self.sound)

我必须继承此对象才能使用它,它可能看起来像这样:

class Dog(Animal):
    def __init__(self):
        self.sound = 'Woof Woof'

我看到它的方式我可以做两件事。第一个是这样的:

dog = Dog()
assert dog.sound == 'Woof Woof'

第二个选项是模拟logging.info并检查它是否被调用。我对他们两人都有不同的感受。

第一个感觉就像我只是测试我的配置而第二个感觉就像我实际上没有测试我想要的对象。

我正在使用这个简单的例子,因为那些不使用Django的人可能会给我一些指示。我遇到的真正问题涉及Django通用视图。

例如,我可以使用此模板视图:

class HomeView(TemplateView):
    template_name = 'home.html'

我是否仅测试template_name是否具有正确的值,还是使用测试客户端进行更高级别的测试来测试整个视图?

3 个答案:

答案 0 :(得分:5)

不,确保正确测试父对象(必要时使用模拟)并分别测试子对象方法。这符合封装概念(使本地成为问题)。

如果不这样做,那么包含许多类的大型项目将耗尽您的所有编码资源而无法增加价值。

答案 1 :(得分:3)

在您的简单示例中,我可能会测试父方法。但是在你的Django案例中,这意味着要测试Django。那不是你的工作! ;-)对我而言,这是单元测试的一个重大问题:不要测试其他人的代码或第三部分库。确保您的部件正确无误。可能听起来很明显,但在现实生活中并不容易 - 至少在我的经历中。

答案 2 :(得分:1)

您显示的测试完全正确 - 您正在测试中重复字符串文字'Woof Woof'

您可以对Animal进行类似的测试:

animal = Animal()
animal.sound = 'sound'
animal.speak()
# test that detects log contains 'sound'

您还可以进行一项测试,其中包含动物列表,例如[Dog, Cat, ...],并检测每个动物的实例是否发出声音。

for animalClass in AnimalList:
    animal = animalClass()
    animal.speak()
    # test that detects log contains animal.sound