How do I assert my exception message with JUnit Test annotation?
我用
这就是我想要的:
1 2 | @Test (expected = RuntimeException.class, message ="Employee ID is null") public void shouldThrowRuntimeExceptionWhenEmployeeIDisNull() {} |
您可以将
1 2 3 4 5 6 7 8 9 | @Rule public ExpectedException expectedEx = ExpectedException.none(); @Test public void shouldThrowRuntimeExceptionWhenEmployeeIDisNull() throws Exception { expectedEx.expect(RuntimeException.class); expectedEx.expectMessage("Employee ID is null"); // do something that should throw the exception... } |
请注意,
我喜欢
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Test (expected = RuntimeException.class) public void myTestMethod() { try { //Run exception throwing operation here } catch(RuntimeException re) { String message ="Employee ID is null"; assertEquals(message, re.getMessage()); throw re; } fail("Employee Id Null exception did not throw!"); } |
你必须使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
实际上,最好的用法是使用try/catch。为什么?因为您可以控制期望异常的地方。
考虑这个例子:
1 2 3 4 5 | @Test (expected = RuntimeException.class) public void someTest() { // test preparation // actual test } |
如果有一天代码被修改,测试准备将抛出runtimeexception,该怎么办?在这种情况下,实际测试甚至没有被测试,即使它没有抛出任何异常,测试也会通过。
这就是为什么使用Try/Catch比依赖注释要好得多的原因。
在Junit 4.13(发布后)中,您可以执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; ... @Test void exceptionTesting() { IllegalArgumentException exception = assertThrows( IllegalArgumentException.class, () -> { throw new IllegalArgumentException("a message"); } ); assertEquals("a message", exception.getMessage()); } |
这也适用于6月5日,但有不同的进口:
1 2 3 4 | import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; ... |
雷斯托姆的回答很好。我也不太喜欢规则。我做了类似的事情,只是我创建了以下实用程序类来帮助可读性和可用性,这是注释的一大优点。
添加此实用程序类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import org.junit.Assert; public abstract class ExpectedRuntimeExceptionAsserter { private String expectedExceptionMessage; public ExpectedRuntimeExceptionAsserter(String expectedExceptionMessage) { this.expectedExceptionMessage = expectedExceptionMessage; } public final void run(){ try{ expectException(); Assert.fail(String.format("Expected a RuntimeException '%s'", expectedExceptionMessage)); } catch (RuntimeException e){ Assert.assertEquals("RuntimeException caught, but unexpected message", expectedExceptionMessage, e.getMessage()); } } protected abstract void expectException(); } |
然后,对于我的单元测试,我只需要以下代码:
1 2 3 4 5 6 7 8 9 | @Test public void verifyAnonymousUserCantAccessPrivilegedResourceTest(){ new ExpectedRuntimeExceptionAsserter("anonymous user can't access privileged resource"){ @Override protected void expectException() { throw new RuntimeException("anonymous user can't access privileged resource"); } }.run(); //passes test; expected exception is caught, and this @Test returns normally as"Passed" } |
如果使用@rule,异常集将应用于测试类中的所有测试方法。
我喜欢用户64141的答案,但发现它可以更广义化。这是我的拿手好戏:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public abstract class ExpectedThrowableAsserter implements Runnable { private final Class<? extends Throwable> throwableClass; private final String expectedExceptionMessage; protected ExpectedThrowableAsserter(Class<? extends Throwable> throwableClass, String expectedExceptionMessage) { this.throwableClass = throwableClass; this.expectedExceptionMessage = expectedExceptionMessage; } public final void run() { try { expectException(); } catch (Throwable e) { assertTrue(String.format("Caught unexpected %s", e.getClass().getSimpleName()), throwableClass.isInstance(e)); assertEquals(String.format("%s caught, but unexpected message", throwableClass.getSimpleName()), expectedExceptionMessage, e.getMessage()); return; } fail(String.format("Expected %s, but no exception was thrown.", throwableClass.getSimpleName())); } protected abstract void expectException(); } |
请注意,将"fail"语句留在try块中会导致捕获相关的断言异常;在catch语句中使用return可防止这种情况发生。
导入catch异常库,并使用它。它比
文档示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import static com.googlecode.catchexception.CatchException.*; import static com.googlecode.catchexception.apis.CatchExceptionHamcrestMatchers.*; // given: an empty list List myList = new ArrayList(); // when: we try to get the first element of the list catchException(myList).get(1); // then: we expect an IndexOutOfBoundsException with message"Index: 1, Size: 0" assertThat(caughtException(), allOf( instanceOf(IndexOutOfBoundsException.class), hasMessage("Index: 1, Size: 0"), hasNoCause() ) ); |