不要在JUnit测试中显示抛出异常信息的堆栈跟踪

13

当测试抛出异常消息的值时,可以像这样:

public void mustFailIfTheActionDoesNotExist() {
        try {
            getAction(UUID.randomUUID().toString());

            fail("Must fail if the action does not exists");
        } catch (MyException ex) {
            Assert.assertEquals("Exception generated on action", ex.getMessage());
        }

异常和它们的堆栈跟踪可以在终端上看到。由于我的项目中有数百个类,终端只是一长串异常消息的堆栈跟踪列表。

当运行Junit测试时,有没有办法抑制异常输出的堆栈跟踪到屏幕/终端上?

附注:我不想为所有单元测试抑制日志记录,只想在特定情况下这样做。


你可以关闭输出流,但是在这个测试用例结束后需要重新打开它。 - AxelH
这似乎与您所说的类似:https://dev59.com/sGXWa4cB1Zd3GeqPQMMj#33871861。但我希望能够禁用堆栈跟踪,因为它主要占用空间。 - goelakash
1
好的,你正在使用什么进行日志记录?你可以使用 System.setOut(PrintStream)System.setErr(PrintStream) 重定向流。将它们保存在某个地方,然后覆盖到一个文件中(以便跟踪)或关闭它们以隐藏所有内容。最后,在结束时将保存的实例重置为系统实例。 - AxelH
我正在使用log4j进行日志记录。 - goelakash
2个回答

5
我猜测你正在测试的代码记录了一个异常并将其抛出。不要这样做。
在非测试代码中捕获异常时,应执行以下操作之一:
  1. 记录异常并继续执行
  2. 重新抛出异常,而不记录它
  3. 包装异常,并抛出未记录任何日志信息的已包装异常
如果这样做,则任何异常最多只会被记录一次。
您还应确保所有异常都在代码的顶层记录。这可能需要调用 Thread.setDefaultUncaughtExceptionHandler() 或 `Thread.setUncaughtExceptionHandler()。

2
在下面的测试中,您可以测试异常是否被抛出。但是,一旦异常被抛出,您不能进行测试(如失败)。它们不会被执行。此外,它也不会打印堆栈跟踪信息。
@Test(expected = MyException.class)
public void mustFailIfTheActionDoesNotExist() throws MyException{
     getAction(UUID.randomUUID().toString());
     fail("Must fail if the action does not exists");
}

如果想在抛出异常后进行测试,你可以查看 ExpectedException Rule

更新:

@Rule
public ExpectedException exception = ExpectedException.none();
@Test
public void shouldNotPrintStackTrace() throws ArithmeticException {
    exception.expect(ArithmeticException.class);
    exception.expectMessage(containsString("by zero"));
    System.out.println(10 / 0);
}

以上代码在成功的情况下不会显示堆栈跟踪,您可以测试消息。如果测试失败,则会打印堆栈跟踪。


1
这样做无法测试异常消息。ExpectedException 可以做到,但也会打印堆栈跟踪。 - goelakash
1
@goelakash请查看我的更新答案。您能否使用ExpectedException分享您的代码,然后我们可以看到哪里出了问题。 - selimssevgi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接