测试异常
预期异常
你如何校验你的代码按照预期抛出异常?完成代码通常是比较简单的,但要确保代码的行为在特殊情况下与预期相同是至关重要的。举个栗子:
new ArrayList<Object>().get(0);
这段代码会抛出一个IndexOutOfBoundsException。@Test注解有一个可选参数"expected",它的值是Throwable的子类,如果我们想要验证ArrayList抛出一个正确的异常,我们只需要写下面这段代码:
@Test(expected = IndexOutOfBoundsException.class)
public void empty() {
new ArrayList<Object>().get(0);
}
expected参数应该需要小心使用,上述代码只要有任何地方抛出IndexOutOfBoundsException就会通过测试,
try/cach 语法
在JUnit 3.X版本中只能使用try/cach来测试异常
@Test
public void testExceptionMessage() {
try {
new ArrayList<Object>().get(0);
fail("Expected an IndexOutOfBoundsException to be thrown");
} catch (IndexOutOfBoundsException anIndexOutOfBoundsException) {
assertThat(anIndexOutOfBoundsException.getMessage(), is("Index: 0, Size: 0"));
}
}
ExpectedException规则
另外,你也可以使用ExpectedException规则,这个规则是表示你不仅关心有异常抛出,而且也关心异常信息:
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void shouldTestExceptionMessage() throws IndexOutOfBoundsException {
List<Object> list = new ArrayList<Object>();
thrown.expect(IndexOutOfBoundsException.class);
thrown.expectMessage("Index: 0, Size: 0");
list.get(0); // execution will never get past this line
}
expectMessage中还可以使用匹配器,使得在测试代码中多了一些灵活性
thrown.expectMessage(JUnitMatchers.containsString("Size: 0"));
此外,你可以使用匹配器来检查异常,如果有用的话它嵌入了要验证的状态。例如
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.startsWith;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
public class TestExy {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void shouldThrow() {
TestThing testThing = new TestThing();
thrown.expect(NotFoundException.class);
thrown.expectMessage(startsWith("some Message"));
thrown.expect(hasProperty("response", hasProperty("status", is(404))));
testThing.chuck();
}
private class TestThing {
public void chuck() {
Response response = Response.status(Status.NOT_FOUND).entity("Resource not found").build();
throw new NotFoundException("some Message", response);
}
}
}
对于规则的ExpectedException的扩展讨论,请参阅此博客