Java JUnit4和异常时挂起

Java JUnit4和异常时挂起,java,debugging,reflection,exception-handling,junit,Java,Debugging,Reflection,Exception Handling,Junit,当代码中抛出未捕获的异常时,我习惯于让调试器在抛出语句处停止,以便在抛出异常时检查局部变量和所有相关对象的成员。使用IntelliJ Idea可以通过运行、查看断点、选择“异常断点”选项卡、检查任何异常并确保选中“捕获的异常”复选框,同时选中“未捕获的异常”复选框来完成此操作。使用Eclipse和visualstudio(对于C#来说)是不同的,但思路相同 使调试器以这种方式运行的能力非常有用;事实上,它非常有用,因此我相应地构造了程序的主循环:在发行版上,主循环当然嵌入了一个try-catch

当代码中抛出未捕获的异常时,我习惯于让调试器在抛出语句处停止,以便在抛出异常时检查局部变量和所有相关对象的成员。使用IntelliJ Idea可以通过运行、查看断点、选择“异常断点”选项卡、检查任何异常并确保选中“捕获的异常”复选框,同时选中“未捕获的异常”复选框来完成此操作。使用Eclipse和visualstudio(对于C#来说)是不同的,但思路相同

使调试器以这种方式运行的能力非常有用;事实上,它非常有用,因此我相应地构造了程序的主循环:在发行版上,主循环当然嵌入了一个try-catch-all中;但在调试版本中,主循环中没有try-catch块,因此程序中任何未捕获的异常都将保持未捕获状态,以便调试器在抛出时暂停程序

但是,当使用JUnit测试Java类时,我遇到了一个问题:调试器不会在任何异常时停止。相反,所发生的不仅是预期的,而且意外的异常也会被自动捕获,并且我会得到一个事后异常堆栈跟踪,以尝试从中获得意义。那不太酷

我曾经认为这是因为JUnit使用了
java.lang.reflect.Method.invoke()
,它捕获所有异常并将它们转换为
TargetInvocationExceptions
,但后来我编写了自己的自定义JUnit runner,它亲自了解我的测试类,直接调用它的方法,而不使用
Method.invoke()
,问题仍然存在。这意味着这个问题在核心JUnit中处于高位

那么,还有其他人有同样的问题吗?是否有人知道一种解决方案,以便在使用JUnit进行测试时,调试器在出现意外异常时暂停程序执行

相关(未回答)问题:

相关(未回答)问题:


相关(部分回答)问题:(公认的答案是“如果在jUnit中调试单个方法,断点开始工作。如果在jUnit中调试整个类或包,则调试器不工作。”)

作为调查测试失败时使用的变通方法,您可以在main方法中创建一个有问题的测试类的实例,并使用exception breakpoints方法手动调用它的测试方法(顺便说一句,这很酷,谢谢您的提问)。这样,该方法就不会被反射性地调用。

我希望我正确理解这个问题,如果我错了,请纠正我,但是:

  • 您有一个测试,它抛出一个异常,您自己没有捕获到它(因此,从这个意义上说,它是未捕获的)
  • 当您使用JUnit4 testrunner调试此测试时,JUnit向您显示测试失败(它引发了异常)
  • 但是线程没有挂起,这是您想要实现的
  • 即使您启用了
    首选项| java | debug |挂起对未捕获异常的执行
在这种情况下,我相信这是预期的行为,JUnit捕获并吞咽您的异常,因此就eclipse而言,它并不是未捕获的,如本文所述


您可以通过为捕获的异常设置自己的挂起规则,以任何方式挂起eclipse<代码>调试透视图|断点视图| J!图标|选中捕获异常时挂起

您正在运行哪个版本的JUnit?我可以在测试中捕获未捕获的异常,EclipseIndigo构建20110615-0604,JUnit4。我使用的是JUnit4.8.1。请注意,这个问题不是关于捕获未捕获的异常;它是关于让调试器在未捕获的异常上暂停程序执行。换句话说,如果抛出的异常是未捕获的,则让
throw
指令像断点一样运行。我的IDE(EclipseIndigo)在捕获/未捕获异常时自动暂停执行(如果我也这么说的话)。甚至在运行JUnit4测试时。哦,我明白了。这很有趣,我会检查一下,然后再回来。@Perception我无法证实你的观察。然而,我发现了一条新的信息,并将其添加到我的答案的最后。(运行整个测试套件与运行单个测试)这与您的观察结果一致吗?谢谢您的回答,但正如您所说,这不是一个真正的解决方案,而是一种变通方法。事实上,只需转到引发异常的行(通过单击堆栈跟踪),在那里放置一个断点,然后重新运行,就更容易了。我只是想避免那样做。你对这个问题的理解是正确的。但是,您提出的解决方案将不起作用,因为在我无法控制的代码中以及在正常操作下的代码中都会抛出数千个异常(已捕获),我甚至不能使用类过滤器来至少处理java运行时抛出和捕获的异常,因为有时java运行时抛出的异常会传播到我的代码中,我希望调试器在我的代码调用抛出的运行时方法的地方中断,但是java调试器显然没有Microsoft Visual Studio那样的“只中断我的代码”的概念。啊,是的,我理解,鉴于我发布的链接,我想你的最后一句话是正确的,eclipse调试器似乎没有只在代码中挂起的概念。这似乎让JUnit不接受您的异常成为您唯一的选择。。。我不知道这是否可能。。。