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