新代码覆盖率的 SonarQube 质量门对于依赖于烘焙到 Java 中的东西的未发现代码失败

SonarQube quality gate on new code coverage fails for uncovered code that relies on things baked into Java

我们团队中有人更改了此代码:

public class Rectangle implements Cloneable, Serializable {

    @Override
    public Rectangle clone() {
        return new Rectangle(x, y, width, height);
    }

}

此代码:

public class Rectangle implements Cloneable, Serializable {

    @Override
    public Rectangle clone() {
        try {
            // super.clone is safe to return since all of the Rectangle's fields are primitive.
            return (Rectangle) super.clone();
        } catch (CloneNotSupportedException e) {
            // should never happen since Cloneable is implemented
            return null;
        }
    }

}

他们编写了涵盖 try 代码路径的单元测试。

他们没有编写涵盖 catch 代码路径的测试。 catch代码路径依赖东西"baked"变成Java,让它崩溃的唯一方法是改变[=89]的结构 =],通过删除 Cloneable 标记界面。但是如果 class 结构发生变化,那么另一个单元测试应该会失败。

因为 catch 代码路径未被单元测试覆盖,SonarQube 质量门 "code coverage on new code" 失败,并且由于质量门失败,构建该分支的 Jenkins 作业失败,由于 Jenkins 作业失败,Bitbucket 将不允许合并。

已经尝试过:

问题

编辑历史记录

Apache Commons Lang 提供了一个 clone 方法,它可以进行深拷贝并且不会抛出异常。没有异常意味着不需要 try/catch,因此要测试的代码路径更少。我在一篇讨论 Object.clone() 替代方案的文章中发现了这一点:https://dzone.com/articles/java-cloning-copy-constructor-vs-cloning

将此添加到 pom.xml:

<dependency>
  <groupId>commons-lang</groupId>
  <artifactId>commons-lang</artifactId>
  <version>2.6</version>
</dependency>

将此添加到您的 class:

的导入语句中
import org.apache.commons.lang.SerializationUtils;

您的 class 必须有 implements Serializable。添加一个 private static final long serialVersionUID,这显然是最佳做法。

然后将super.clone()替换为SerializationUtils.clone(this)

最后,您可以删除 clone() 语句周围的 try/catch,或从方法中删除 trows

这是我的新代码:

@Override
public Rectangle clone() {
    return (Rectangle) SerializationUtils.clone(this);
}

它已经被之前的单元测试覆盖了,那个单元测试仍然通过。