1. 概述

本文将深入探讨 AssertJ 库,重点介绍如何定义和使用条件(Conditions)来编写可读性强且易于维护的测试代码。

AssertJ 基础知识可参考此处

2. 测试目标类

先看下我们要测试的目标类:

public class Member {
    private String name;
    private int age;

    // 构造方法和getter
}

3. 创建条件

我们可以通过实例化 Condition 类来定义断言条件。

最便捷的方式:使用接收 Predicate 参数的构造函数。其他构造函数需要创建子类并重写 matches 方法,相对繁琐。

创建 Condition 对象时必须指定类型参数,表示被测试值的类型。

下面为 Member 类的 age 字段定义条件:

Condition<Member> senior = new Condition<>(
  m -> m.getAge() >= 60, "senior");

senior 变量现在引用了一个 Condition 实例,用于判断 Member 是否为老年人(基于年龄)。

⚠️ 构造函数的第二个参数:字符串 "senior" 是简短描述,当条件失败时,AssertJ 会用它构建友好的错误信息。

另一个检查姓名是否为 "John" 的条件:

Condition<Member> nameJohn = new Condition<>(
  m -> m.getName().equalsIgnoreCase("John"), 
  "name John"
);

4. 测试用例

现在看如何在测试类中使用 Condition 对象。假设 seniornameJohn 条件已作为测试类的字段存在。

4.1. 断言标量值

以下测试应通过,因为 age 值超过老年阈值:

Member member = new Member("John", 65);
assertThat(member).is(senior);

由于 is 方法断言成功,使用 isNot 方法会失败:

// 断言失败,错误信息包含 "not to be <senior>"
assertThat(member).isNot(senior);

使用 nameJohn 变量可编写类似测试:

Member member = new Member("Jane", 60);
assertThat(member).doesNotHave(nameJohn);

// 断言失败,错误信息包含 "to have:\n <name John>"
assertThat(member).has(nameJohn);

语义说明is/hasisNot/doesNotHave 方法语义相同,选择哪个纯属个人偏好。但建议选择使测试代码更易读的方法。

4.2. 断言集合

条件不仅适用于标量值,还可验证集合中元素的存在或缺失。看个例子:

List<Member> members = new ArrayList<>();
members.add(new Member("Alice", 50));
members.add(new Member("Bob", 60));

assertThat(members).haveExactly(1, senior);
assertThat(members).doNotHave(nameJohn);

haveExactly 断言满足条件的元素数量,doNotHave 检查不存在满足条件的元素。

📚 更多方法haveExactlydoNotHave 并非全部,完整列表见 API 文档中的 AbstractIterableAssert 类

4.3. 组合条件

可通过 Assertions 类的三个静态方法组合条件

  • not – 创建当指定条件不满足时成立的条件
  • allOf – 创建当所有指定条件都满足时成立的条件
  • anyOf – 创建当至少一个指定条件满足时成立的条件

notallOf 的组合示例:

Member john = new Member("John", 60);
Member jane = new Member("Jane", 50);
        
assertThat(john).is(allOf(senior, nameJohn));
assertThat(jane).is(allOf(not(nameJohn), not(senior)));

anyOf 的使用示例:

Member john = new Member("John", 50);
Member jane = new Member("Jane", 60);
        
assertThat(john).is(anyOf(senior, nameJohn));
assertThat(jane).is(anyOf(nameJohn, senior));

5. 总结

本文介绍了 AssertJ 条件的使用方法,以及如何通过它们在测试代码中编写高可读性的断言。

所有示例代码和片段可在 GitHub 项目 中找到。


原始标题:Using Conditions with AssertJ Assertions | Baeldung

« 上一篇: Java Weekly, 第215期
» 下一篇: Java中的观察者模式