Mat*_*ski 32 java junit cobertura
我正在使用JUnit4和Cobertura的静态方法测试一个帮助器类.测试方法很容易,已经完成.
但是,cobertura表明该类完全没有被测试覆盖,因为它没有在任何地方实例化.
我不想创建这个类的实例(它是一个帮助类),所以第一个解决方案是隐藏构造函数(这通常是帮助类的好方法).
然后cobertura抱怨空的私有构造函数不受测试覆盖.
是否有任何解决方案可以实现100%的代码覆盖率?
顶级管理层(在这种情况下)需要代码覆盖率,因此对于我来说,获得100%的特定课程是非常有帮助的.
Aar*_*lla 31
有几种解决方案:
您可以添加公共构造函数并从测试中调用它.虽然它没有意义,但它也没有受到伤害(很多).
创建一个虚拟静态实例(您可以在此处调用私有构造函数).丑陋,但你可以给该字段一个名称来传达你的意图(JUST_TO_SILENCE_COBERTURA是一个好名字).
您可以让测试扩展帮助程序类.这将本质上调用默认构造函数,但你的帮助程序类不能再final了.
我建议最后一种方法,特别是因为课程不能再进行final了.如果代码的使用者想要添加另一个辅助方法,他们现在可以扩展现有的类并接收一个句柄来获取所有辅助方法.这创建了一个辅助方法的耦合,它传达意图(这些属于一起) - 如果是辅助类,这是不可能的final
如果要防止用户意外地实例化帮助程序类,请创建它abstract而不是使用隐藏的构造函数.
mat*_*att 29
如果你绝对需要实现100%的代码覆盖率 - 其优点可以在别处争论:) - 你可以在测试中使用反射实现它.作为习惯,当我实现一个静态实用程序类时,我添加了一个私有构造函数,以确保无法创建该类的实例.例如:
/**
* Constructs a new MyUtilities.
* @throws InstantiationException
*/
private MyUtilities() throws InstantiationException
{
throw new InstantiationException("Instances of this type are forbidden.");
}
Run Code Online (Sandbox Code Playgroud)
那你的测试可能看起来像这样:
@Test
public void Test_Constructor_Throws_Exception() throws IllegalAccessException, InstantiationException {
final Class<?> cls = MyUtilties.class;
final Constructor<?> c = cls.getDeclaredConstructors()[0];
c.setAccessible(true);
Throwable targetException = null;
try {
c.newInstance((Object[])null);
} catch (InvocationTargetException ite) {
targetException = ite.getTargetException();
}
assertNotNull(targetException);
assertEquals(targetException.getClass(), InstantiationException.class);
}
Run Code Online (Sandbox Code Playgroud)
基本上,你在这里做的是按名称获取类,在类类型上找到构造函数,将其设置为public(setAccessible调用),不带参数调用构造函数,然后确保抛出的目标异常是一个InstantiationException.
无论如何,正如你所说,这里100%的代码覆盖率要求是一种痛苦,但听起来它不在你手中,所以你无能为力.我实际上在我自己的代码中使用了类似于上面的方法,我确实发现它有益,但不是从测试的角度来看.相反,它只是帮助我学习了一些比我之前知道的更多的反思:)
在所有情况下获得100%的覆盖率是好的,但在某些情况下这是不可能的.当然,如果你有一个从未实例化的类,Cobertura会把它作为一个不完整的测试覆盖,因为这些代码行实际上在类中,但它们没有经过测试.
事实是你永远不会调用私有构造函数(我假设你通过私有构造函数隐藏了构造函数),所以我不会打扰.测试应该是关于获得你期望的,虽然我同意100%的覆盖率是好的,在某些情况下(像这样),这是没有用的.
看看100%的代码覆盖率.
| 归档时间: |
|
| 查看次数: |
24195 次 |
| 最近记录: |