JUnittesting – 分析预期的exception

在JUnit中,我目前使用注解来预期在我的testing中有一个exception。

有没有办法分析这个exception? 例如,我期望一个CriticalServerException ,但我也想validationgetMessage方法的内容。

如果您有JUnit 4.7或更高版本,请尝试ExpectedException

在这个问题中有一个例子,复制如下:

 @Rule public ExpectedException exception = ExpectedException.none(); @Test public void testRodneCisloRok(){ exception.expect(IllegalArgumentException.class); exception.expectMessage("error1"); new RodneCislo("891415",dopocitej("891415")); } 

我不确定你是否应该。 使用try-catch块来检查错误消息是如此的平庸 。 现在我们有了这个很酷的function,你可以编写@Test(expected=CriticalServerException.class)并且想要返回并使用try-catch来获取你期望的exception,只是为了检查错误信息?

国际海事组织你应该留下@Test(expected=CriticalServerException.class)注释,并忽略错误消息。 检查错误信息,可以改变很多,因为它是一个更“人”可读的string,而不是技术价值,也可能是棘手的。 您强制exception具有特定的错误消息,但是您可能不知道是谁生成了exception以及他select了哪个错误消息。

一般来说,您要testing方法是否引发exception,而不是实际的错误消息。 如果错误信息真的非常重要,你应该考虑使用它引发的exception的子类,并在@Test(expected=...)检查它。

 try{ //your code expecting to throw an exception fail("Failed to assert :No exception thrown"); } catch(CriticalServerException ex){ assertNotNull("Failed to assert", ex.getMessage()) assertEquals("Failed to assert", "Expected Message", ex.getMessage()); } 
 try { // your code fail("Didn't throw expected exception"); } catch(CriticalServerException e) { assertEquals("Expected message", e.getMessage()); } 
 try { // test code invacation fail("Exception not throw!!!"); } catch(CriticalServerException ex) { assertTrue("Invalid exception data", ex.toString().contains("error text")); } 

如果您有很多testing用例需要testing,请使用MethodRule作为常用解决scheme

 public class ExceptionRule implements MethodRule { @Override public Statement apply(final Statement base, final FrameworkMethod method, Object target) { return new Statement() { @Override public void evaluate() throws Throwable { try { base.evaluate(); Assert.fail(); } catch (CriticalServerException e) { //Analyze the exception here } } }; } } 

然后使用规则到你的testing类:

 @Rule public ExceptionRule rule = new ExceptionRule(); 

我不认为有使用注释的方法。 你可能不得不退后一步,在catch块中的try-catch方法中validation消息

使用catch-exception :

 catchException(obj).doSomethingCritical(); assertTrue(caughtException() instanceof CriticalServerException); assertEquals("Expected Message", caughtException().getMessage()); 

看stream利的exception规则 ,它“结合了Junit ExpectedException规则和AssertJ的断言方便性”。

 import pl.wkr.fluentrule.api.FluentExpectedException; ... @Rule public FluentExpectedException thrown = FluentExpectedException.none(); @Test public void testDoSomethingCritical() { thrown.expect(CriticalServerException.class).hasMessage("Expected Message").hasNoCause(); obj.doSomethingCritical(); } 

如果你想比较消息和exceptiontypes,那么你可以尝试下面的代码片段。

  @Rule public ExpectedException expectedException = ExpectedException.none(); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("Parameter is not valid"); //check string contains expectedException.expectMessage(CoreMatchers.equalTo("Parameter is not valid")); //check string equals 

注意:这将适用于junit 4.9以上。

Java 8解决scheme

这是我写的一个实用函数:

 public final <T extends Throwable> T expectException( Class<T> exceptionClass, Runnable runnable ) { try { runnable.run(); } catch( Throwable throwable ) { if( throwable instanceof AssertionError && throwable.getCause() != null ) throwable = throwable.getCause(); //allows "assert x != null : new IllegalArgumentException();" assert exceptionClass.isInstance( throwable ) : throwable; //exception of the wrong kind was thrown. assert throwable.getClass() == exceptionClass : throwable; //exception thrown was a subclass, but not the exact class, expected. @SuppressWarnings( "unchecked" ) T result = (T)throwable; return result; } assert false; //expected exception was not thrown. return null; //to keep the compiler happy. } 

( 取自我的博客 )

使用它如下:

 @Test public void testThrows() { RuntimeException e = expectException( RuntimeException.class, () -> { throw new RuntimeException( "fail!" ); } ); assert e.getMessage().equals( "fail!" ); } 

此外,如果您想了解一些原因,请查看以下信息: https : //softwareengineering.stackexchange.com/a/278958/41811