我得到了 emma 为我的 java 代码报告的几乎 100% 的覆盖率,除了一个类中的一大块行(没有突出显示,只有类本身被突出显示)。
有问题的“方法”如下所示:
$SWITCH_TABLE$com$ ...STUFF... (): int []
这可能指的是什么?它似乎是某种自动生成的方法,我无法追踪到任何实际的代码行/无法弄清楚如何对其进行测试等。
请帮忙。:)
仔细看看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%,您可以随意修改并通过反射调用它:
@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% 的另一个原因。
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); }