使用逻辑or(| |)和Java';短路,什么';JaCoCo要我满足的第四个条件是什么?

使用逻辑or(| |)和Java';短路,什么';JaCoCo要我满足的第四个条件是什么?,java,sonarqube,jacoco,short-circuiting,test-coverage,Java,Sonarqube,Jacoco,Short Circuiting,Test Coverage,这可能是一个相当简单的问题,但我不知所措 我有一个if语句,如下所示: if(TheEnum.A.equals(myEnum) || TheEnum.B.equals(myEnum)) thenum可以是A,B,CG(不止4个选项) JaCoCo(SONAR)告诉我这里有四个条件。 那些是什么? 在这个例子中,我能测试的不是整个集合吗 if(true || not_evaluated) => true if(false || true) => true if(false || fa

这可能是一个相当简单的问题,但我不知所措

我有一个if语句,如下所示:

if(TheEnum.A.equals(myEnum) || TheEnum.B.equals(myEnum))
thenum
可以是
A
B
C
<代码>G(不止4个选项)

JaCoCo(SONAR)告诉我这里有四个条件。 那些是什么? 在这个例子中,我能测试的不是整个集合吗

if(true || not_evaluated) => true
if(false || true) => true
if(false || false) => false
我很确定我不能专门测试
if(true | true)
如果(真|假)
, 因为短路评估不会走那么远


如果是这样,JaCoCo/Sonar想让我测试的第四个选项是什么?

你说得对,这个代码是短路。它被编译成字节码,大致如下所示(假设Java已经goto):


因此,当JaCoCo分析字节码时,从它的角度来看,有两个独立的检查:第一个是
if
,第二个是
if
,它们生成四个可能的分支。你可以认为这是一个JACOCO错误,但我认为这不是很容易修复这一点,它不是很令人不安,所以你可以忍受它。

< P >如果100%分比什么都重要。 ... 使用这种方法:

if (Boolean.logicalOr(TheEnum.A.equals(myEnum), TheEnum.B.equals(myEnum))) {
    ...
或者使用二进制或

if (TheEnum.A.equals(myEnum) | TheEnum.B.equals(myEnum)) {
    ...
您可以将调用嵌套到任意深度,或使用自己的
函数:

if (or(TheEnum.A.equals(myEnum), TheEnum.B.equals(myEnum))) {
    ...

public static boolean or(Boolean... vals) {
    for (Boolean v : vals) {
        if (Boolean.TRUE.equals(v))
        return true;
    }
    return false;
}
使用独立的可测试函数
将对其进行100%的测试

请注意,这可能会影响性能。。。我告诉过你!
同时,隐藏所有这些决定可能会适得其反

试试非短路
|
,看看JaCoCo是怎么说的。我发现这种行为非常令人费解。对我来说,实际上并不是短路不能让你同时测试(真、真)和(真、假)两种情况,而是情况(真、真)
不可能存在。如果myEnum是A,那么它是
而不是
B。在给定的代码片段中,我只能看到三种情况
myEnum
必须是(A、B,而不是-A或-B)之一。这是三种情况。嗯,它减少了覆盖范围。有了95%的目标,再加上在一个短期课程中的一些目标,这确实有点重要……;)@Christian是时候向您的经理解释高覆盖率并不意味着高质量;)@克里斯蒂安:有很多情况下你不能得到100%的保险。例如,方法内的断言。或者
clone()
方法中的
catch(CloneNotSupportedException ex)
。另一方面,100%的覆盖率并不是万能的。历史上有很多很酷的bug,尽管100%的覆盖率都没有被注意到。例如。使用
(a+b)/2
计算平均值。它只是简单地覆盖它,它没有分支,但是如果你不在大于
Integer.MAX_VALUE/2
的数字上测试它,你就不会注意到错误。
if (or(TheEnum.A.equals(myEnum), TheEnum.B.equals(myEnum))) {
    ...

public static boolean or(Boolean... vals) {
    for (Boolean v : vals) {
        if (Boolean.TRUE.equals(v))
        return true;
    }
    return false;
}