Why is it considered a bad practice to test a class by extending it?
据我所知,测试一个类有两种主要方法。
测试类扩展被测试的类
测试类创建被测试的类(组合)
据我所知,第一种方法被认为是一种不好的做法。
但为什么呢?
-
petrikainulainen.net/programming/unit-testing/&
-
类FooTest的实例不需要是Foo的实例。永远不应该存在使用FooTest的实例代替Foo实例的情况。
-
@AndyTurner,一个优势可能是暴露受保护的方法,但我想它也被认为是一种不好的做法(测试受保护的方法)
-
受保护的protected方法,测试不是"必要的",但是需要使用protected方法测试所有public方法
-
您可以阅读junit和java:测试关于非公共方法测试的非公共方法。它应该回答你的问题,为什么不需要继承你正在测试的类。现在,你的问题的答案主要是基于意见,在我的"意见"中,所以我不相信我们可以轻易回答"不良做法"
-
UnitTest验证被测代码的公共可观察行为。公共意味着其他生产代码调用此方法。这并不意味着被测代码通过public带注释的方法暴露了这种行为,但通常它会这样做。
-
实际上,您使用的两个选项(继承/组合)都没有使用。相反,测试类包含测试方法,其中测试方法内部将测试中的类的实例创建为本地临时对象。有时测试类包含被测试类的对象作为成员对象,这样使用Setup函数可以避免一些代码重复,但这是一个非常测试特定的组合使用。
-
关于私有/受保护等内容的测试:单元测试是关于发现错误。错误在实现中 - 不同的实现,不同的可能错误。将Fibonacci视为迭代/递归函数,闭合表单表达式(Moivre / Binet),查找表:接口始终相同,可能的错误显着不同。此外,在查看coverage时,您始终会查看实现,而不是界面。你如何设计你的课程,以便你真正可以测试实现细节是一个不同的故事......
对我来说,单元测试有两个主要目的:
验证测试对象是否按照我的预期进行操作
记录如何正确使用测试类
通过扩展测试类,测试接缝可能会改变类的行为。 这对于测试来说是不好的实践。
有时我甚至会修复例如当前时间依赖性,如果DI不是选项:
1 2 3 4 5 6 7 8 9 10 11
| private InstanceToTest instance ;
private Calendar now = new GregorianCalendar(2019, 4, 4, 13, 23, 47);
@Before
public void initInstance () {
instance = new InstanceToTest () {
@Override
Calendar getNow () {
return now ;
}
};
} |
现在我可以测试2019年4月4日13:23:47以使测试稳定。
有时我想分别测试提取的内部方法。 我更喜欢将这些方法包私有化。 这样我可以从我的测试中调用它们(如果它在测试源文件夹中的同一个包中)而不覆盖它们。