gpt4 book ai didi

java - 为什么 JaCoCo 没有覆盖我的 String switch 语句?

转载 作者:太空狗 更新时间:2023-10-29 22:33:48 25 4
gpt4 key购买 nike

我有一个从 String 中提取寻址模式的 switch 语句,我已经编写了单元测试来涵盖,我认为是所有可能发生的事情,但 JaCoCo 似乎跳过我的 switch 语句,导致覆盖率较低。

为什么,如果我的所有 case 语句(包括 default)都在测试中执行,那么 switch 语句不会算作命中吗?

enter image description here

最佳答案

对于字符串的切换

class Fun  {
static int fun(String s) {
switch (s) {
case "I":
return 1;
case "A":
return 2;
case "Z":
return 3;
case "ABS":
return 4;
case "IND":
return 5;
default:
return 6;
}
}
}

Oracle Java 编译器生成的字节码类似于以下代码(Eclipse Compiler for Java 生成的字节码略有不同)

    int c = -1;
switch (s.hashCode()) {
case 65: // +1 branch
if (s.equals("I")) // +2 branches
c = 0;
break;
case 73: // +1 branch
if (s.equals("A")) // +2 branches
c = 1;
break;
case 90: // +1 branch
if (s.equals("Z")) // +2 branches
c = 2;
break;
case 64594: // +1 branch
if (s.equals("ABS")) // +2 branches
c = 3;
break;
case 72639: // +1 branch
if (s.equals("IND")) // +2 branches
c = 4;
break;
default: // +1 branch
}
switch (c) {
case 0: // +1 branch
return 1;
case 1: // +1 branch
return 2;
case 2: // +1 branch
return 3;
case 3: // +1 branch
return 4;
case 4: // +1 branch
return 5;
default: // +1 branch
return 6;
}

因此,原始的 6 种情况的 switch 语句在字节码中表示为 StringhashCode 的 6 种情况的开关加上 5 个 if 语句加上另一个 6 的开关个案。要查看此字节码,您可以使用 javap -c

JaCoCo 执行字节码分析,并且在低于 0.8.0 的版本中没有针对字符串切换的过滤器。您的测试涵盖 if 语句中的条件评估为 true 的情况,但不包括它们评估为 false 的情况。我个人建议简单地忽略遗漏的情况,因为目标不是测试编译器是否生成正确的代码,而是测试您的应用程序是否正确运行。但为了这个答案的完整性 - 这里是涵盖所有字节码分支的测试:

import org.junit.Test;
import static org.junit.Assert.*;

public class FunTest {
@Test
public void test() {
// original strings:
assertEquals(1, Fun.fun("I"));
assertEquals(2, Fun.fun("A"));
assertEquals(3, Fun.fun("Z"));
assertEquals(4, Fun.fun("ABS"));
assertEquals(5, Fun.fun("IND"));

// same hash codes, but different strings:
assertEquals(6, Fun.fun("\0I"));
assertEquals(6, Fun.fun("\0A"));
assertEquals(6, Fun.fun("\0Z"));
assertEquals(6, Fun.fun("\0ABS"));
assertEquals(6, Fun.fun("\0IND"));

// distinct hash code to cover default cases of switches
assertEquals(6, Fun.fun(""));
}
}

JaCoCo 0.7.9生成的报告作为证明:

coverage report

JaCoCo version 0.8.0 provides filters ,包括 javac 为按字符串切换而生成的字节码过滤器。因此即使没有额外的测试也会生成以下报告:

coverage report

关于java - 为什么 JaCoCo 没有覆盖我的 String switch 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42642840/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com