JUnit: testing helper class with only static methods
我正在用JUnit4和Cobertura测试一个只使用静态方法的助手类。测试方法很简单,已经完成了。
但是,cobertura表明类没有完全被测试覆盖,因为它没有在任何地方实例化。
我不想创建这个类的实例(它是一个助手类),所以第一个解决方案是隐藏构造函数(这通常是助手类的好方法)。
然后,Cobertura抱怨空的私有构造函数没有被测试覆盖。
对于这种情况,是否有实现100%代码覆盖率的解决方案?
顶级管理层(在本例中)需要代码覆盖率,因此对于我来说,获得这个特定类的100%是非常有帮助的。
有几种解决方案:
可以添加公共构造函数并从测试中调用它。虽然它没有意义,但它也没有多大的伤害。
创建一个虚拟静态实例(您可以在这里调用私有构造函数)。丑陋,但你可以给字段一个名字来传达你的意图(
您可以让测试扩展helper类。这本质上会调用默认的构造函数,但您的助手类不能再是
我建议使用最后一种方法,特别是因为类不能再是
如果要防止用户意外地实例化helper类,请将其设置为
如果您绝对需要实现100%的代码覆盖率——这一点的优点可以在其他地方讨论:)——您可以在测试中使用反射来实现它。作为习惯,当我实现一个仅静态的实用程序类时,我会添加一个私有的构造函数来确保类的实例不能被创建。例如:
1 2 3 4 5 6 7 8 | /** * Constructs a new MyUtilities. * @throws InstantiationException */ private MyUtilities() throws InstantiationException { throw new InstantiationException("Instances of this type are forbidden."); } |
那么您的测试可能看起来像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @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); } |
基本上,您在这里所做的是按名称获取类,查找该类类型的构造函数,将其设置为public(
不管怎样,正如您所说,这里的100%代码覆盖率要求有点痛苦,但听起来这是您无法控制的,所以您几乎无能为力。实际上,我在自己的代码中使用了与上面类似的方法,我确实发现这是有益的,但不是从测试的角度。相反,它只是帮助我学到了比以前更多的关于思考的知识。
在所有情况下获得100%的覆盖率是好的,但在某些情况下这是不可能的。当然,如果您有一个从未实例化的类,那么cobertura将得到一个不完整的测试覆盖率,因为这些代码行实际上在类中,但它们没有被测试。
事实上,您永远不会调用私有构造函数(我假设您已通过使其私有化来隐藏该构造函数),所以我不会麻烦您。测试应该是得到你所期望的,虽然我同意100%的覆盖率是好的,但在某些情况下(像这样),这是没有用的。
看看100%的代码覆盖率。
不。
除非您显式地调用私有构造函数(这将是错误的代码),否则您将无法覆盖这些行。