10

在一个项目中,我有一个Utility 类,如下所示:

public final class Util {
    private Util() {}
    public static String method1(InputStream in) {...}
    public static String method2(BufferedReader in) {...}
    public static String method3(File file) {...}
}

该类是一个实用程序类,因为它只包含static方法。因此它被声明final并且它的构造函数是private. 创建实例或派生子类根本没有任何意义。

我有一套单元测试来测试项目。我正在使用IntelliJ IDEA来运行测试、测量和可视化代码覆盖率。Utility 的构造函数class Util现在降低了覆盖率。我希望看到 100% 的 100% 逻辑覆盖率。像 Utility 类的私有构造函数这样的代码会降低覆盖率。

是否有可能(最好通过注释)将方法或构造函数标记为与代码覆盖率无关,以便从覆盖率报告中排除此类代码,从而显示 100% 的覆盖率?

我知道,一般来说,从覆盖率报告中隐藏代码对你自己不利。我不介意报告是否会有“被忽略的项目”列表 - 实际上,这会很好,以检查是否有人忽略了不应忽略的内容。关键在于覆盖范围毫无意义的代码,例如 Utility 类的私有构造函数。

我试图找出是否annotations.jar包含候选人。唯一看起来似乎可以做到的注释是TestOnly,但它并没有达到这个目的。我也四处看了plugins/coverage/lib/*.jar看,找不到候选人,但也许我只是错过了?

更新 这个问题现在已经过时了。与此同时,IntelliJ IDEA 和 Jacoco 学会了如何忽略没有调用者的私有构造函数的覆盖。我不知道有任何其他 Java 中故意无法访问的代码示例会引发从覆盖率报告中排除的对话。

更新 2 这个问题可能再次与 Java 记录类的访问器相关。

4

2 回答 2

10

enum用于实用程序类,大多数覆盖工具都知道忽略它的方法。

public enum Util { ;

enum默认情况下final带有private构造函数。

于 2015-01-02T21:56:52.140 回答
4

这个问题目前已有一年多的历史了;但是,我认为我可以提供一个替代方法来忽略单元测试中的私有构造函数。尽管不太可能,但可以绕过 Java 中的私有构造函数。此外,将来可能会修改该类,有人可以添加构造函数等...进行单元测试来验证这一点可能会让人觉得多余,但它确实增加了另一个层次的意图清晰度。失败的单元测试肯定会引起我的注意,“我导致单元测试失败,我确定我知道我在这里要改变什么吗?”

事不宜迟,这里有一些示例代码。

这里我们有一个带有私有构造函数的类。

public final class ClassWithPrivateCtor
{
  private ClassWithPrivateCtor()
  {
    throw new AssertionError(String.format(
      "Illegal instantiation of class: %s.",
      this.getClass().getName()));
  }
}

这是在 Java 中调用私有构造函数的一种方法。

private static <T> void invokePrivateConstructor(final Class<T> type)
  throws Throwable
{
  final Constructor<T> constructor = type.getDeclaredConstructor();

  constructor.setAccessible(true);

  try
  {
    constructor.newInstance();
  }
  catch (InvocationTargetException ex)
  {
    throw ex.getTargetException();
  }
}

这就是我在单元测试中使用它的方式。

@Test(
  description = "Verify ClassWithPrivateCtor private constructor fails.",
  expectedExceptions = AssertionError.class)
public void classWithPrivateCtorTest()
  throws Throwable
{
  invokePrivateConstructor(ClassWithPrivateCtor.class);
}

我已经养成了以这种方式验证私有构造函数的习惯,只是为了清楚该类的初衷,无论它是实用程序类还是具有常量的类等......

于 2016-04-25T16:35:29.037 回答