Maven Emma的意思是:$ SWITCH_TABLE $

时间:2012-09-12 08:17:36

标签: java maven emma

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

有问题的'方法'列为:

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

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

请帮忙。 :)

2 个答案:

答案 0 :(得分: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不在涵盖范围内,但您无法对此做任何事情。

来源和变体

我的主要来源是this article on enum并且正在玩JAD(我建议使用以下参数:-a -dead -noconv -nocast -noclass -v)。

文章提到$SwitchMap$$SWITCH_TABLE$几乎相同,只是在方法内部使用了内部类中的static intializer。这可能是由于旧版本的Java或编译器差异造成的。

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和一些反思。我认为这是他们通常set the bar at 80-90%的另一个原因。

答案 1 :(得分:0)

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

e.g。

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

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

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