单元测试之断言

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写的

posted @ 2025-03-30 23:32  halu126  阅读(50)  评论(0)    收藏  举报