代码覆盖率未达到类声明

11

有没有办法让代码覆盖率覆盖像这样的类声明?

public class MyClass{

    public static void foo(int bar){
        System.out.println("The Number is: "+bar);
    }
}

我可以轻松使用JUnit测试命中foo方法,但MyClass声明保持红色。这是因为该类本身没有构造函数吗?如果是这样,是否有任何方法可以覆盖代码的那一部分,而不更改类本身的代码呢?

谢谢


1
不相关,但是这个类是否应该被实例化?如果不是,它可能应该有一个私有构造函数。 - Tyler MacDonell
2
代码覆盖率告诉你哪些是被执行的。声明不是可执行代码。 - Ira Baxter
1
带着一定的保留态度看待这个问题:来自一个曾在一家实行代码覆盖率要求的商店工作过的人,我知道它们之所以愚蠢,是因为你的覆盖率工具突然想要捕捉类的声明 - Makoto
因此,有人可能会将“class”行标记为已执行,作为标记不可见默认构造函数的劣质替代品。但这是一种艺术选择,在实践中几乎没有什么影响,因为默认构造函数不做任何事情,你不能对它们进行有用的测试。我也遇到过一些商店希望将类之间的空白行标记为已覆盖,以便在极端情况下文件获得100%的覆盖率。当你坚持使用line覆盖时就会出现这种情况。如果你选择分支覆盖,你可以在不过度覆盖声明或空白行的情况下获得100%的覆盖率。 - Ira Baxter
@IraBaxter 实际上,我今天在 StackOverflow 上寻找答案的原因是我的代码覆盖率报告显示我没有覆盖一个分支,而那行代码是类声明。所以我猜这种情况仍然可能发生,但我一直在寻找是否有其他人曾经遇到过这种情况。 - Hakanai
@Trejkaz:许多Java“测试覆盖率”工具查看字节码以发现“分支”。在Java编译器由于类声明生成字节码分支的程度上,您可以获得该效果。一些Java测试覆盖工具仅查看Java源代码中的分支,因此不会看到字节码内部的分支,从而避免提供错误报告。 - Ira Baxter
2个回答

11
这可能取决于您特定的环境。但是我刚刚检查了Eclipse / EclEmma,并看到了您描述的行为。
请记住,该类确实具有构造函数-默认构造函数。如果您创建一个简单调用new MyClass()的测试,它看起来像红色标记消失了。
但是,对于仅具有静态方法的类,首选方法是将类标记为final并创建一个私有构造函数。当然,如果您创建一个私有构造函数,那么在代码覆盖中会显示为红色-因为您无法调用私有构造函数!
最后,请记住,代码覆盖率是一种工具。我不会因为查看器中的红色标记而感到紧张。

2
当你在工作中被强制使用SonarQube,因此红色标记意味着你的PR不会通过时,说出"不要为了一个红色标记而变得紧张"这样的话就变得非常容易。 - Hakanai

2

你的问题让我不得不给出两个评论,而不是直接回答:

  1. 除非有非常好的理由,否则不要使用 static 关键字。

    一种普遍的误解是,用于提供共同功能的类应该具有(仅)static 方法。这来自于将只有 static 方法的类称为 utility classes 的习惯。

    这样的 all static 实用程序类将使您的代码难以扩展和重用。并且您会扔掉面向对象编程中最强大的工具之一:多态性。而您唯一的优势就是不需要编写构造函数调用...

  2. 寻找 CodeCoverage 很容易,因为我们有工具可以给出这方面的数字,而管理人员喜欢评判开发人员的数字产出...

    但更重要的是 requirement coverage。不幸的是,我们没有工具来衡量 requirement coverage。达到 100% requirement coverage 的唯一工具是测试/行为驱动开发(TDD/BDD)。


这里的第一点取决于具体情况。也许你正在完全采用函数式编程风格编写代码,那么在静态方法中拥有许多纯函数对我来说似乎完全没有问题。你仍然可以获得可重用性,只是在不同的层面上。 - Hakanai
@ Trejkaz,您的观点只考虑了短期。如果要求变化并且您必须支持不同版本的某个方法以支持数据的不同处理方式呢?采用您的方法,您必须更改方法签名以添加一个选择性参数破坏现有的代码,而实际上又不需要它。如果您没有static访问权限,则可以仅在需要时使用子类,而其他人甚至不会注意到。(开闭原则) - Timothy Truckle
通常即使以函数式风格编写代码,我也会将所有选项打包到某种容器中(甚至哈希表也足够了),这样您就不必更改实际的方法参数。 - Hakanai
@Trejkaz:“我会将所有选项都归为某种容器中[...],这样你就不必更改实际的方法参数。”-- 这意味着你永远无法通过查看方法签名来知道它需要哪个参数。这不是你老师告诉你的那种“信息隐藏”... ;o) - Timothy Truckle
你可以轻松地使用继承来创建相同的问题,如果你正在创建需要比超类更多参数的子类方法。你是否曾经看到过一个类层次结构,其中一些子类需要关闭而其他子类则不需要? ¯\( ツ) - Hakanai
@Trejkaz 简而言之:当我遇到这样糟糕的设计时,我会改进它。 - Timothy Truckle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接