2

我得到了 emma 为我的 java 代码报告的几乎 100% 的覆盖率,除了一个类中的一大块行(没有突出显示,只有类本身被突出显示)。

有问题的“方法”如下所示:

$SWITCH_TABLE$com$ ...STUFF... (): int []

这可能指的是什么?它似乎是某种自动生成的方法,我无法追踪到任何实际的代码行/无法弄清楚如何对其进行测试等。

请帮忙。:)

4

2 回答 2

3

仔细看看STUFF,它应该是一个枚举。

枚举的表开关

当您在枚举上编写开关时,例如:

STUFF stuff;
public String getWho() {
    switch(this.stuff) {
        case THINGIE: return "kid";
        case MATERIAL: return "scientist";
        default: return "people";
    }
}

编译器基于 生成开关表Enum.ordinal,“生成”是在 中调用的方法中完成的switch,例如:

switch( ($SWITCH_TABLE$com$...STUFF...())[this.stuff.ordinal] )

也许您只部分介绍了该方法。如果只测试getWho()一次,生成的方法会错过一个分支,因为返回int[]的是惰性初始化的。另一种可能是catch生成方法中的 es 没有被覆盖,但你对此无能为力。

来源和变体

我的主要来源是这篇关于枚举和玩JAD的文章(我建议使用以下参数:) -a -dead -noconv -nocast -noclass -v

文章提到除了在方法内部使用内部类之外$SwitchMap$几乎相同。这可能是由于 Java 版本较旧或编译器差异所致。$SWITCH_TABLE$static intializer

100%

如果您真的决心达到 100%,您可以随意修改并通过反射调用它:

@Test
public void testSwitches() {
    for(Method m : NotCovered.class) {
        if(m.getName().startsWith("$SWITCH_TABLE$")) {
            m.setAccessible(true);
            m.invoke(null); // one for lazy init
            m.invoke(null); // one for quick returning the initialized value
        }
    }
}

我没有尝试这个代码,也没有建议使用它,只是一个例子。

在我早期的日子里,我曾尝试在专业环境中达到 100%,而在最后的 12% 中,我需要大量的测试编码和模拟。对于最后 3%,我需要PowerMock和一些反思。我认为这是他们通常将标准设置为 80-90% 的另一个原因。

于 2014-06-06T23:18:46.920 回答
0

Emma 可能会抱怨您不希望执行的代码部分。在这种情况下,我怀疑您有一个不需要调用的桥接方法。

例如

class A<N extends Number> {
    void method(N n) { }
}

class B extends A<Integer> {
    void method(Integer n) { }
}

在这种情况下,B 类有两种方法。一个是void method(Integer),但这不会从 JVM 的角度覆盖 A 中的那个,它会重载它,因此会生成另一种“桥”方法,即void method(Number n) { method((Integer) n); }

于 2012-09-12T08:22:39.340 回答