【问题标题】:JUnit 4 and Suspend-on-ExceptionJUnit 4 和异常挂起
【发布时间】:2012-11-28 18:12:07
【问题描述】:

当在我的代码中抛出未捕获的异常时,我习惯于让调试器在抛出语句处停止,以便在抛出异常的那一刻检查局部变量和所有涉及的对象的成员。使用 IntelliJ Idea,这可以通过转到 RunView Breakpoints、选择 Exception Breakpoints 选项卡、检查任何异常,并确保未选中 Caught exception 复选框,同时选中 Uncaught exception 复选框。 EclipseVisual Studio(用于 C#)是不同的,但路线相同。

让调试器以这种方式运行的能力非常有用;实际上非常有用,以至于我相应地构建了程序的主循环:在发布版本上,主循环当然嵌入在 try-catch-all 中;但是在调试版本中,主循环中没有 try-catch 块,因此任何在我的程序中任何地方都没有被捕获的异常都将保持未被捕获,这样调试器就会在它们被抛出的那一刻暂停我的程序。

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

我曾经认为这是因为 JUnit 使用了java.lang.reflect.Method.invoke(),它捕获所有异常并将它们转换为TargetInvocationExceptions,但后来我编写了自己的自定义 JUnit 运行器,它亲自和直接知道我的测试类在没有Method.invoke() 的情况下调用其方法,问题仍然存在。这意味着问题出在核心 JUnit 内部。

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

相关(未回答)问题:Suspend on uncaught runtime exceptions in Eclipse Junit test runner

相关(未回答)问题:How to break into debugger within a jUnit test case?

相关(部分回答)问题:Break on Exception in Eclipse using jUnit(接受的答案是“如果您在 jUnit 中调试单个方法,则断点开始工作。如果在 jUnit 中调试整个类或包,则调试器不会”不行。”)

【问题讨论】:

  • 您运行的是什么版本的 JUnit?我可以很好地在测试中捕获未捕获的异常,Eclipse Indigo Build 20110615-0604,JUnit 4。
  • 我使用的是 JUnit 4.8.1。请注意,这个问题不是关于捕获未捕获的异常;它是关于让调试器在未捕获的异常上暂停程序执行。换句话说,如果抛出的异常未被捕获,那么throw 指令的行为就像断点一样。
  • 我想我不清楚。我的 IDE(Eclipse Indigo)在捕获/未捕获异常时自动暂停执行,如果我也告诉它的话。即使在运行 JUnit 4 测试时。
  • 哦,我明白了。这很有趣,我会检查它,我会回复它。
  • @Perception 我无法确认您的观察。但是,我发现了一条新信息,并在答案的最后添加了它。 (运行整个测试套件与运行单个测试。)这是否符合您的观察?

标签: java debugging reflection exception-handling junit


【解决方案1】:

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

  • 你有一个测试,它抛出了一个你自己没有发现的异常(所以从这个意义上说,它是未被捕获的)
  • 当您使用 JUnit4 测试运行程序调试此测试时,JUnit 显示测试失败(它引发了异常)
  • 但是线程没有挂起,这是你想要实现的
  • 即使您启用了preferences | java | debug | suspend execution on uncaught exceptions

在这种情况下,我相信这是预期的行为,JUnit 会捕获并吞下您的异常,因此就 eclipse 而言,它并非未被捕获,如此处所述https://bugs.eclipse.org/bugs/show_bug.cgi?id=414133

您可以通过设置自己的规则来暂停捕获的异常,从而以任何方式暂停 Eclipse。 Debug perspective | breakpoint view | J! icon | check suspend on caught exception

【讨论】:

  • 你对问题的理解是正确的。但是,您提出的解决方案将不起作用,因为在我无法控制的代码中、在正常操作下的代码中以及在我的用于测试目的的代码中都会引发数千个异常(被捕获)错误检查和处理代码。
  • 我什至不能使用类过滤器来至少处理 java 运行时抛出和捕获的异常,因为有时 java 运行时抛出的异常会传播到我的代码,我想要调试器在我的代码调用抛出的运行时方法的地方中断,但 java 调试器显然没有像 Microsoft Visual Studio 那样“只中断我的代码”的概念。
  • 啊,是的,我明白了,鉴于我发布的链接,我猜你的最后一句话是正确的,eclipse 调试器似乎没有只在你的代码中暂停的概念。这似乎让 JUnit 不要把你的异常作为你唯一的选择......我不知道这是否可能......
【解决方案2】:

作为调查测试失败时使用的一种解决方法,您可以在 main 方法中创建有问题的测试类的实例,并使用您的异常断点方法手动调用其测试方法(顺便说一句,这非常酷,谢谢问题)。这样,该方法就不会被反射调用。

【讨论】:

  • 感谢您的回复,但正如您所说,这不是真正的解决方案,而是一种解决方法。事实上,直接转到抛出异常的行(通过单击堆栈跟踪)更容易在此处放置一个断点,然后重新运行。我只是想避免这样做。
猜你喜欢
  • 2011-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-12
  • 2017-07-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-27
相关资源
最近更新 更多