环境: Linux,Eclipse Juno,Java 7,JUnit
当一个简单的应用程序(带有main方法的java类)在调试模式下运行时,' Drop to Frame'功能在Eclipse中运行良好。但是,如果从junit测试用例中调用相同的方法,则“删除到帧”' Eclipse中禁用了该功能。从文档
注意此命令仅在当前VM支持drop to时可用 框架和所选的堆栈框架不是顶部框架或框架中的框架 原生方法。
正如我们在调试窗口中的堆栈帧中看到的那样,当运行junit测试用例时,有一个框架' NativeMethodAccessorImpl.invoke'这是原生的。我假设这是“掉到框架”的原因'被禁用。
如果这种推理是正确的,请告诉我,如果是,可以使用任何解决方法来解决此问题。
答案 0 :(得分:8)
我在Windows下使用Eclipse Luna,Java 7。
情况仍然如下所述:对于紧跟在“NativeMethodAccessorImpl.invoke”框架之后的测试方法,禁用“Drop to frame”。
“Drop to frame”的禁用状态绑定到类canDropToFrame()
中相应supportsDropToFrame()
的方法org.eclipse.jdt.internal.debug.core.model.JDIStackFrame
,
(在我的发行版中)plugins/org.eclipse.jdt.debug_3.8.102.v20150115-1323/jdimodel.jar
的一部分。
方法supportsDropToFrame()检查是否可以删除特定的帧,并测试
所以Ramesh的假设是正确的。 这是测试3 + 4的原始代码段:
int index = 0;
JDIStackFrame frame = null;
while (index < frames.size()) {
frame = (JDIStackFrame) frames.get(index);
index++;
if (frame.isNative()) {
return false;
}
if (frame.equals(this)) {
if (jdkSupport) {
// JDK 1.4 VMs are currently unable to pop the
// frame directly above a native frame
if (index < frames.size()
&& ((JDIStackFrame) frames.get(index))
.isNative()) {
return false;
}
}
return true;
}
}
评论表明它是用JDK编写的1.4次,所以也许在此期间JVM现在也可以将帧丢弃到本机帧之上。
我创建了JDIStackFrame的修补版本,跳过了测试4。 现在,当在Junit测试方法中暂停时,“Drop to frame”已按预期启用。
但是当实际丢弃帧时,我收到一个错误消息框,上面写着 “com.sun.jdi.InternalException:回复时出现错误代码:32出现了弹出堆栈帧”。
我认为这是一个JDWP错误代码。 因此,似乎这样的“Drop to frame”在JDK 1.7中不起作用(不知道1.8),并且它不是Eclipse的东西。
答案 1 :(得分:0)
这是一个古老的版本,但是就目前而言,这仍然是Eclipse 2018-09,Java 1.8和testng作为测试运行程序的问题。解决方法(简单明了)是将测试的内容提取到另一种方法中,对其进行调试,然后将其内联。例如:
@Test
public void test() {
// test goes here
assertTrue(true);
}
一个人可以使用重构快捷方式来加快速度:选择测试的主体,按Alt + Shift + M,输入名称“ inner”,结果为:
@Test
public void test() {
inner();
}
private void inner() {
// test goes here and 'drop-to-frame' works well
assertTrue(true);
}
调试完成后,在inner()内部按Alt + Shift + I将其内联。
答案 2 :(得分:0)
我总是通过在 @Test
函数和我可以将帧放入其中的 thunk 之间拆分来处理这个问题。
在 JDK-8 之前,我会这样做:
@Test
public void testSomeFooInBar() {
drop_to_frame_testSomeFooInBar();
}
private void drop_to_frame_testSomeFooInBar() {
assertTrue(somethingOrWhatever);
}
即使它很冗长,我还是坚持/坚持在测试函数之后调用我的thunks,名称表明它们的用途(“跳转/降帧”)。这总是必要的,因为总是有人在不阅读评论的情况下进行“重构”,并开始将 thunk 删除为“不必要的”。
使用 JDK 8 及更高版本,我这样做:
@Test
public void testSomeFooInBar() {
final Runnable drop_to_frame = () -> {
assertTrue(somethingOrWhatever);
};
jump_to_frame.run();
}
更简单。 Eclipse 将允许您在可运行的 lambda 内设置断点,并根据需要多次进入帧(假设您的逻辑具有足够的可重入性。)