java - 对于依赖于嵌入 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不允许合并。
已经尝试过:
- 失败:在 SonarQube 中标记为误报:代码覆盖质量门不可能,您只能针对基于规则的问题执行此操作。
- DIRTY HACK:在运行作业之前关闭(或降低)SonarQube 中的质量门,并在分支合并后重新打开:这可行,但感觉太脏了,我认为它应该发生得非常特别。我正在寻找一种不需要人工干预的更好的解决方案。
- FAILED: Mocking
Rectangle
: 不起作用,super.clone()
必须模拟,这是 onObject.clone()
,这是一个受保护的方法。 - FAILED:通过添加一个附加类来伪造它,例如
Rectangle
->EvilRectangle
->TestRectangle
,其中EvilRectangle
抛出CloneNotSupportedException
and thenTestRectangle
是为测试实例化的实际类。不起作用,因为这会改变方法的签名,clone()
它不会抛出CloneNotSupportedException
.Rectangle
问题
- 爪哇人:
- 如何为
catch
代码路径编写单元测试? - 如何在不更改其公共 API 的情况下重写代码,使其变得可测试?
- SonarQube 人
- 如何使质量门“新代码的代码覆盖率”通过?
编辑历史
- 添加了原始代码
解决方案
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/catch
aroundclone()
语句,或trows
从方法中删除。
现在这是我的新代码:
@Override
public Rectangle clone() {
return (Rectangle) SerializationUtils.clone(this);
}
之前的单元测试已经涵盖了它,并且该单元测试仍然通过。
推荐阅读
- javascript - 仅路径下的 SVG 填充区域
- intellij-idea - 如何在 JetBrains IDE 中查看多个文件观察器的输出
- node.js - 如何从另一个部署 Alexa Skill 的处理程序调用处理程序?
- javascript - 搜索对象数组以匹配来自 mongodb 的 objectId
- php - 使用 jquery 多图像选择和打印选定的图像
- c# - PHP RSA公共加密不匹配C#加密
- google-dfp - 无法在 Google Ad Manager 中添加新用户(例如:DFP)
- java - JavaFX 13:列表视图在打开和关闭新窗口后不更新项目
- c# - 可以在 C# 中使用 SQL AND 语句来引用多个 C# 变量吗?如果是这样,怎么做?
- java - Java JSONObject.getJSONArray 总是返回 null