我应该对从父类继承的方法进行单元测试吗?

8
我目前正在以TDD的方式编写JDBC驱动程序的实现(是的,你没看错),虽然我目前只完成了类存根和一些小的功能,但我突然想到,由于Statement是PreparedStatement的超类,而PreparedStatement又是CallableStatement的超类,当我真正开始为这些类的实现编写测试时,我应该做什么呢?
以下是我可以采取的方法:
1. 为Statement创建一个测试套件,然后扩展该套件以进行PreparedStatement和CallableStatement的其他测试。
2. 忽略从超类继承的方法,分别测试每个实现。
3. 为每个实现类严格测试每个方法。毕竟,有些继承的方法在不同的实现中可能有所不同。稍微变化一下,我将测试实现使用的所有继承方法。
我觉得第二个方法最自然,但由于我提出的原因,我不确定是否明智这样做。那么,您认为我应该怎么做呢?
4个回答

11

针对每个实现类单独测试每个方法是必要的。

特别地,不正确地覆盖超类方法是一个常见的错误。子类的作者对超类进行了假设。当超类发生变化时,子类就会出问题。


2
这将是正确的做法。您需要确保所有方法仍然有效。 - Roger C S Wernersson
假设我有超类 A 和子类 BCA 有一个方法 a()BC 都没有重写它。你的意思是,尽管如此,我的测试需要测试 A.a()B.a()C.a(),即使它正在测试完全相同的方法(BC 都没有重写它,只是继承它)三次??我猜在测试时就不要考虑 DRY 原则了。 - Don Cheadle
为每个实现类单独测试每个方法,这是正确的。但是如果我有20个公共方法,在任何子类中都没有被覆盖,那该怎么办呢?为什么要在每个实现中都测试它们?这样做不会增加任何价值,肯定会导致重复。 - Farid

7

如果这意味着你将为每个测试子类重复运行相同的测试,则我绝对不会选择替代方案1(让测试类层次结构与实际类层次结构相同)。此外,我一般对除了通用实用基类之外的测试类进行子类化持怀疑态度。

我通常为层次结构中的每个类编写一个测试,无论是抽象的还是非抽象的。因此,基类有一个单独的测试(通常使用一个测试特定的私有子类来进行测试),我利用我的子类知识为每个子类编写适当的测试。我可以在覆盖率运行中看到缺少测试的内容,因此我通常不会过于正式地进行前期规划。


4

提供足够的测试,以便您感到舒适-基于您对实现的了解。我不将单元测试视为完全的黑盒测试。如果您知道基类从未调用任何虚拟方法(或至少没有被覆盖的虚拟方法),则请注意这一事实,但不要有效地重复您已经拥有的单元测试。

单元测试可以被推到极致-始终值得平衡您从中获得的价值和它所花费的努力。


1

使用TDD时,您不应该针对测试方法进行测试,而是针对代码的行为或能力进行测试。因此,在实现子类时,您可以仅限于测试与基类不同的行为。如果有疑问,请编写新的测试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接