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

2 投票
3 回答
615 浏览
提问于 2025-04-16 16:03

假设我在使用一个框架,这个框架里有一个叫做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 个回答

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
3

在你这个简单的例子中,我可能会测试父类的方法。但是在你提到的Django的情况下,这就意味着要测试Django本身。而这不是你的工作!;-) 对我来说,这就是单元测试的一个大问题:不要去测试别人写的代码或者第三方的库。要确保你自己写的部分是正确的。这听起来可能很明显,但在实际操作中并没有那么简单——至少在我的经验里是这样。

5

不,确保父对象经过了正确的测试(如果需要,可以使用模拟技术),并且要单独测试子对象的方法。这符合封装的概念(把事情局部化)。

如果不这样做,一个包含很多类的大项目会耗尽你所有的编码资源,但并没有带来额外的价值。

撰写回答