我正在用JUnit4和Cobertura测试一个只有静态方法的helper类。测试方法很容易,而且已经完成了。
但是,cobertura表明类并没有被测试完全覆盖,因为它在任何地方都没有示例化。
我不想创建这个类的示例(它是一个帮助类),所以第一个解决方案是隐藏构造函数(这通常是帮助类的好方法)。
然后cobertura抱怨空的私有构造函数没有被测试覆盖。
对于这种情况,是否有任何解决方案可以实现100%的代码覆盖率?
代码覆盖率是顶层管理所必需的(在本例中),所以对我来说,获得这个特定类的100%覆盖率是非常有帮助的。
7条答案
按热度按时间fumotvh31#
有几种解决方案:
1.你可以添加一个公共构造函数,然后从测试中调用它。虽然这没有什么意义,但也没有什么坏处。
1.创建一个虚拟的静态示例(你可以在这里调用私有构造函数)。很难看,但是你可以给予字段一个名字来表达你的意图(
JUST_TO_SILENCE_COBERTURA
是一个好名字)。1.你可以让你的测试扩展帮助类,这将内在地调用默认的构造函数,但是你的帮助类不能再是
final
。我建议使用最后一种方法,特别是因为类不能再是
final
。如果代码的消费者想添加另一个helper方法,他们现在可以扩展现有的类,并接收一个句柄来访问所有helper方法。这将创建一个helper方法的耦合,用于传达意图(这些方法属于一起)--如果helper类是final
,这是不可能的如果要防止用户意外地示例化helper类,请将其设置为
abstract
,而不是使用隐藏的构造函数。crcmnpdw2#
如果你绝对需要实现100%的代码覆盖率--其优点可以在其他地方讨论:)--你可以在测试中使用反射来实现它。作为习惯,当我实现一个只支持静态的实用类时,我会添加一个私有构造函数来确保类的示例不能被创建。例如:
然后,您的测试可能如下所示:
基本上,您在这里所做的就是通过名称获取类,找到该类类型的构造函数,将其设置为public(
setAccessible
调用),不带参数调用构造函数,然后确保抛出的目标异常是InstantiationException
。无论如何,正如您所说,这里的100%代码覆盖率要求是一种痛苦,但它听起来似乎超出了您的控制范围,因此您对此无能为力。实际上,我在自己的代码中使用了类似于上述的方法,我确实发现它是有益的,但不是从测试的Angular 来看。相反,它只是帮助我比以前更多地了解了反射:)
holgip5t3#
在所有情况下都能获得100%的覆盖率是很好的,但是在某些情况下这是不可能的。当然,如果你有一个类从未被示例化,Cobertura会把它作为一个不完整的测试覆盖率,因为那些代码行实际上在类中,但是它们没有被测试。
事实上,你永远不会调用私有构造函数(我假设你已经通过将其设为私有来隐藏构造函数),所以我不会费心。测试应该是关于获得你所期望的,虽然我同意100%覆盖是好的,但在某些情况下(像这样)这是没有用的。
请同时查看100% Code Coverage。
yebdmbv44#
不,不,不
除非您显式调用私有构造函数(这将是错误的代码),否则您将无法覆盖这些行。
6tdlim6h5#
lombok@UtilityClass在我的例子中将代码覆盖率提高到了100%。
njthzxwz6#
你可以跳过100%的覆盖率。这应该不会有什么坏处。但是,如果你正在开发一个非常严格的产品,目标是100%的覆盖率,那么你可以使用下面的策略:
在您的示例中,缺少的覆盖率是构造函数:您应该测试建构函式的预期行为。
如果不定义构造函数,则允许示例化类(通过默认构造函数)。应测试默认构造函数行为:在测试中,呼叫建构函式并测试结果,例如,没有掷回错误,或传回有效的执行严修。
相反,如果作为实用程序类的实践,您还将构造函数定义为
private
,并在构造函数中抛出一个UnsupportedOperationException
。在测试中,您可以Assert该行为。qkf9rpyu7#
在junit 5(jupiter)上,当您使用静态方法向类添加私有构造函数时,覆盖率为100%。