2012-02-21 32 views
19
例外测试

我们正在测试在我们单位的异常时,忽略堆栈跟踪测试在JUnit

@Test(expected=IOException.class) 
    public void test() { 
    // run some code that throws IOException. 
} 

该测试合格,但作为运行测试的Maven构建的一部分,堆栈跟踪来在控制台输出。 有没有办法可以在测试中忽略堆栈跟踪。

+0

我有同样的问题。我们有单元测试,为了代码覆盖尝试从我们的代码中诱发异常。一般来说,我喜欢我们的代码覆盖率很高,但输出中的所有堆栈跟踪都很让人分心。在junit中具有内置功能将会非常好,特别是如果您可以通过注释控制行为。 +1 – 2012-09-18 22:36:02

+0

http://stackoverflow.com/questions/156503/how-do-you-assert-that-a-certain-is-thrown-in-junit-4-tests - 使用ExpectedException Junit规则。 – JeeBee 2015-03-16 15:27:14

+0

这也刺激了我。 – 2016-11-04 20:05:00

回答

4

有没有一个很好的方式来做到这一点,它不值得。我认为打印堆栈跟踪从所谓的代码来了,而不是从你的测试代码:

public class ExpectedExceptionTest { 
    @Test(expected = IOException.class) 
    public void test() throws Exception { 
    foobar(); 
    } 

    public void foobar() throws IOException { 
    try { 
     throw new IOException(); 
    } catch (IOException e) { 
     e.printStackTrace(System.err); 
     throw e; 
    } 
    } 
} 

在这里,它出现在Maven构建日志堆栈跟踪信息从这个方法的错误处理未来的你”重新尝试测试。你不想改变这个错误处理。如果测试失败,那么你想知道发生了什么。

如果您更改它,那么它也使测试中的代码不必要地复杂化。除了这个特定的测试之外,你总是希望stacktrace出现。

那么,我们可以设置System.err为null,正如其他地方所建议的?不,如果你打电话

System.setErr(null); 

然后这将导致NullPointerException(与上述错误处理)。

如果您使用log4j或类似的日志记录,则可以使用@Rule将日志记录级别临时设置为INFO,以避免日志中出现异常。再一次地,如果测试失败,当你最需要它时,调试将不会出现。

我在项目构建输出中一直得到这些异常堆栈跟踪。我只是接受它,并祝贺我自己,我是正确的测试错误条件:-)

15
<plugin> 
    <artifactId>maven-surefire-plugin</artifactId> 
    <version>2.7.1</version> 
    <configuration> 
     <redirectTestOutputToFile>true</redirectTestOutputToFile> 
    </configuration> 
</plugin> 

将上面的代码放到你的pom.xml的插件部分。 redirectTestOutputToFile将从控制台输出中删除堆栈跟踪。显然,用您正在使用的版本替换surfire的版本。

顺便说一下redirectTestOutputToFile参数也可以在failsafe plugin中找到,所以您可以将它应用到集成测试中。

+0

这是干净的,非侵入性的。感谢您的提示。 – 2017-08-14 17:18:14

1

Ÿ解决断言,我居然赶上预期的异常没有看到堆栈跟踪是

@Test 
public void test() { 
    try { 
// run some code that throws IOException. 
    } catch (Exception ex) { 
     assertTrue(ex.getClass().equals(IOException.class)); 
    } 
} 
+0

不处理由他人编写的e.printStackTrace()内部代码。 – 2016-11-16 01:53:33

+0

如果不抛出异常,则编辑解决方案以断言false。但我同意这比完全关闭有价值的日志记录到System.err – 2017-06-22 03:28:46

+0

如果它确实有效,我喜欢这个答案。虽然我不相信。 – djangofan 2017-07-17 21:42:25

-1

其中之一,你可以做的事情,是不使用预期的异常特征。有时我会这样做,当测试数量过多时,我不想让一个真正的异常被忽略,因为maven构建已经打印出预期的期望。

boolean exceptionOccured = false; 
try { 
    // My test here); 
} catch (ExpectedException ex) { 
    exceptionOccured = true; 
} 
if(!exceptionOccured) { 
    Asser.fail(); 
} 
+0

不处理其他人编写的e.printStackTrace()内部代码。 – 2016-11-16 01:53:30

3

System.err是打印到的内容,它是可在运行时修改的PrintStream。所以在System.err的,把从打印出任何一个OutputStream提出了新的PrintStream时write(int i)叫做:

System.setErr(new PrintStream(new OutputStream(){public void write(int i){}}));

记住要备份系统当前的PrintStream。尽管在完成压制输出之后仍然存在错误,否则您将不会收到其他可能对实际知道有用的错误。

你可以在BeforeClass中备份和设置假,并在AfterClass或类似的东西中恢复。


其他注意事项:

这里有一个更全面的组线,你可以把你的测试:

java.io.PrintStream realErrorStream = System.err; 
System.setErr(new java.io.PrintStream(new java.io.OutputStream(){public void write(int i){}})); 
... 
System.setErr(realErrorStream); 
+0

我可以证实这个作品,并适用于OP(不像其他任何响应)。 – 2016-11-16 01:37:01

-1

以我为例,我做的assertNotNull在catch块抛出的异常。这样,如果在代码中发生的反转,我会得到assertNotNull失败。是的如果stacktrace被打印,没有什么可恨的。它有一个原因。

//Building the precondition for test case goes here. 
try { 
    begin();  
    System.out.println("Expected ConstraintViolationException occurred"); 
    dao.save(myObject);    
    commit(); 
} catch (Exception e){ 
    assertNotNull(e); 
} finally { 
    rollback(); 
} 
+0

不处理其他人编写的e.printStackTrace()内部代码。 – 2016-11-16 01:53:37