AssertJ 对异常执行断言
Contents
1. 概述
在这个快速教程中,我们将了解AssertJ 的 异常专用断言。
2. 没有AssertJ
为了测试是否抛出了异常,我们需要捕获异常然后执行断言:
try {
// ...
} catch (Exception e) {
// assertions
}
但是,如果没有抛出异常怎么办?在这种情况下,测试将通过;这就是为什么必须手动失败测试用例的原因。
3. 使用 AssertJ
使用 Java 8,我们可以通过利用 AssertJ 和 lambda 表达式轻松地对异常进行断言。
3.1. 使用assertThatThrownBy()
让我们检查索引列表中的越界项是否会引发IndexOutOfBoundsException:
assertThatThrownBy(() -> {
List<String> list = Arrays.asList("String one", "String two");
list.get(2);
}).isInstanceOf(IndexOutOfBoundsException.class)
.hasMessageContaining("Index: 2, Size: 2");
注意可能引发异常的代码片段是如何作为 lambda 表达式传递的。
当然,我们可以在这里利用各种标准 AssertJ 断言,例如:
.hasMessage("Index: %s, Size: %s", 2, 2)
.hasMessageStartingWith("Index: 2")
.hasMessageContaining("2")
.hasMessageEndingWith("Size: 2")
.hasMessageMatching("Index: \\d+, Size: \\d+")
.hasCauseInstanceOf(IOException.class)
.hasStackTraceContaining("java.io.IOException");
3.2. 使用assertThatExceptionOfType
思路和上面的例子差不多,但是我们可以在开头指定异常类型:
assertThatExceptionOfType(IndexOutOfBoundsException.class)
.isThrownBy(() -> {
// ...
}).hasMessageMatching("Index: \\d+, Size: \\d+");
3.3. 使用assertThatIOException和其他常见类型
AssertJ 为常见的异常类型提供了包装器,例如:
assertThatIOException().isThrownBy(() -> {
// ...
});
同样:
- assertThatIllegalArgumentException()
- assertThatIllegalStateException()
- assertThatIOException()
- assertThatNullPointerException()
3.4. 将异常与断言分开
编写单元测试的另一种方法是在单独的部分中编写when和then逻辑:
// when
Throwable thrown = catchThrowable(() -> {
// ...
});
// then
assertThat(thrown)
.isInstanceOf(ArithmeticException.class)
.hasMessageContaining("/ by zero");