首页 > 解决方案 > 对于依赖于嵌入 Java 的内容的未发现代码,SonarQube 对新代码覆盖率的质量门失败

问题描述

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

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代码路径的测试。代码路径依赖于“烘焙”到 Java 中的catch东西,使其崩溃的唯一方法是通过删除标记接口来更改类的结构。Cloneable但是,如果该类结构发生变化,那么其他单元测试应该会失败。

因为catch代码路径没有被单元测试覆盖,SonarQube 质量门“新代码的代码覆盖率”失败,并且因为质量门失败,构建该分支的 Jenkins 作业失败,并且因为 Jenkins 作业失败,Bitbucket不允许合并。

已经尝试过:

问题

编辑历史

标签: javaunit-testingsonarqube

解决方案


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>

将此添加到您的类的导入语句中:

import org.apache.commons.lang.SerializationUtils;

你的班级必须有implements Serializable. 添加一个private static final long serialVersionUID,这显然是一个最佳实践。

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

最后,您可以删除try/catcharoundclone()语句,或trows从方法中删除。

现在这是我的新代码:

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

之前的单元测试已经涵盖了它,并且该单元测试仍然通过。


推荐阅读