单元测试之断言
Junit5的原生断言
junit-jupiter-api包里的Assertions类中已经提供了很多基础的断言方法,也能满足许多测试场景,但是使用一些第三方的断言库,能增强测试代码的可读性和灵活性,帮助你更高效地编写测试用例。
正如官方文档所说的那样:
即使 JUnit Jupiter 提供的断言工具足以满足许多测试场景,但有时也需要更强大的功能和额外的功能,例如匹配器。在这种情况下,JUnit 团队建议使用第三方断言库,例如 AssertJ、Hamcrest、Truth 等。因此,开发人员可以自由使用他们选择的断言库。
我选择的就是AssertJ。
不好意思,没有对原生断言过多的介绍,下面我们直接来看AssertJ的使用。
AssertJ 简介
AssertJ 是一个流式断言库,语法自然且支持链式调用,适合复杂对象、集合、异常等场景。他有以下特点:
-
流式断言:通过链式调用(Fluent API)编写自然语言的断言逻辑。
-
丰富断言方法:支持字符串、集合、对象、异常、文件、日期等复杂类型的断言。
-
可扩展性:可自定义断言,适配特定领域对象(如自定义类)。
Maven 依赖
<dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>${assertj-core.version}</version> <!-- 检查最新版本 --> <scope>test</scope> </dependency>
使用
对象断言
class Person { String name; int age; // 省略构造器和getter } @Test void objectAssertions() { Person person = new Person("Bob", 25); assertThat(person) .extracting("name", "age") // 提取字段 .containsExactly("Bob", 25); // 链式断言对象属性 assertThat(person) .hasFieldOrPropertyWithValue("name", "Bob") .matches(p -> p.getAge() > 20); }
异常断言
@Test void exceptionAssertions() { // 验证是否抛出异常,并检查异常信息 assertThatThrownBy(() -> { throw new IOException("File not found"); }) .isInstanceOf(IOException.class) .hasMessageContaining("not found"); // 另一种写法 assertThatExceptionOfType(IOException.class) .isThrownBy(() -> { throw new IOException(); }) .withMessage("%s not found", "File"); }
集合与数组断言
@Test void collectionAssertions() { List<String> list = Arrays.asList("a", "b", "c"); assertThat(list) .hasSize(3) .contains("a", "b") // 不关心顺序 .containsExactlyInAnyOrder("c", "b", "a") // 任意顺序 .allMatch(s -> s.length() == 1); // 所有元素满足条件 // 过滤后的断言 assertThat(list) .filteredOn(s -> s.startsWith("a")) .containsExactly("a"); }
字符串断言
@Test void stringAssertions() { String text = "Hello AssertJ!"; assertThat(text) .contains("Assert") .doesNotContain("JUnit") .matches("^Hello.*J!$") // 正则匹配 .hasSize(14); }
日期与时间断言
@Test void dateAssertions() { LocalDate date = LocalDate.of(2023, 10, 1); assertThat(date) .isAfter("2023-09-30") .isEqualTo("2023-10-01"); }
完
以上都是静态导入的 import static org.assertj.core.api.Assertions.*;
AssertJ功能很强大,以上几个小栗子已经可以应付常见的场景了,记录下方便查找
参考
官方文档:https://assertj.github.io/doc/
以上例子都是deepseek写的