1. 概述

本文主要关注AssertJ与Java 8相关的特性,是系列文章的第三篇。

如果你想要了解其主要特性的详细信息,可以参考系列文章的第一篇:AssertJ入门,然后是AssertJ与Guava集成

2. Maven依赖

自版本3.5.1起,Java 8的支持已经包含在了AssertJ核心模块中。为了使用此模块,你需要在pom.xml文件中添加以下依赖:

这个依赖只涵盖了基本的Java断言。如果你想使用高级断言,需要单独添加额外的模块。

你可以在这里找到最新的Core版本:这里

3. Java 8特性

AssertJ通过提供特殊的辅助方法和针对Java 8类型的新断言,利用Java 8的功能。

3.1. Optional断言

首先创建一个简单的Optional实例:

Optional<String> givenOptional = Optional.of("something");

现在我们可以轻松地检查Optional是否包含值以及该值是什么:

assertThat(givenOptional)
  .isPresent()
  .hasValue("something");

3.2. Predicate断言

通过检查String的长度创建一个简单的Predicate实例:

Predicate<String> predicate = s -> s.length() > 4;

现在你可以轻松地检查哪些StringPredicate接受或拒绝:

assertThat(predicate)
  .accepts("aaaaa", "bbbbb")
  .rejects("a", "b")
  .acceptsAll(asList("aaaaa", "bbbbb"))
  .rejectsAll(asList("a", "b"));

3.3. LocalDate断言

首先定义两个LocalDate对象:

LocalDate givenLocalDate = LocalDate.of(2016, 7, 8);
LocalDate todayDate = LocalDate.now();

现在你可以轻松地检查给定日期是否在另一个日期之前或之后,或者是否为今天:

assertThat(givenLocalDate)
  .isBefore(LocalDate.of(2020, 7, 8))
  .isAfterOrEqualTo(LocalDate.of(1989, 7, 8));

assertThat(todayDate)
  .isAfter(LocalDate.of(1989, 7, 8))
  .isToday();

3.4. LocalDateTime断言

LocalDateTime断言的工作方式类似于LocalDate,但不共享isToday方法。

创建一个示例LocalDateTime对象:

LocalDateTime givenLocalDate = LocalDateTime.of(2016, 7, 8, 12, 0);

现在你可以检查:

assertThat(givenLocalDate)
  .isBefore(LocalDateTime.of(2020, 7, 8, 11, 2));

3.5. LocalTime断言

LocalTime断言的工作方式与其他java.util.time.*断言类似,但它们有一个独有的方法:hasSameHourAs

创建一个示例LocalTime对象:

LocalTime givenLocalTime = LocalTime.of(12, 15);

现在你可以断言:

assertThat(givenLocalTime)
  .isAfter(LocalTime.of(1, 0))
  .hasSameHourAs(LocalTime.of(12, 0));

3.6. FlatExtracting辅助方法

FlatExtracting是一个特殊的工具方法,它利用Java 8的lambda表达式从Iterable元素中提取属性。

首先创建一个简单的List,其中包含LocalDate对象:

List<LocalDate> givenList = asList(ofYearDay(2016, 5), ofYearDay(2015, 6));

现在我们可以轻松检查这个List是否至少包含一个2015年的LocalDate对象:

assertThat(givenList)
  .flatExtracting(LocalDate::getYear)
  .contains(2015);

flatExtracting方法不限于字段提取。我们可以随时提供任何函数:

assertThat(givenList)
  .flatExtracting(LocalDate::isLeapYear)
  .contains(true);

甚至:

assertThat(givenList)
  .flatExtracting(Object::getClass)
  .contains(LocalDate.class);

你也可以一次提取多个属性:

assertThat(givenList)
  .flatExtracting(LocalDate::getYear, LocalDate::getDayOfMonth)
  .contains(2015, 6);

3.7. Satisfies辅助方法

Satisfies方法允许你快速检查对象是否满足提供的所有断言。

创建一个示例String实例:

String givenString = "someString";

现在我们可以提供一个lambda体作为断言:

assertThat(givenString)
  .satisfies(s -> {
    assertThat(s).isNotEmpty();
    assertThat(s).hasSize(10);
  });

3.8. HasOnlyOneElementSatisfying辅助方法

HasOnlyOneElement辅助方法允许检查Iterable实例中恰好只有一个元素满足提供的断言。

创建一个示例List

List<String> givenList = Arrays.asList("");

现在你可以断言:

assertThat(givenList)
  .hasOnlyOneElementSatisfying(s -> assertThat(s).isEmpty());

3.9. Matches辅助方法

Matches辅助方法允许检查给定的对象是否匹配提供的Predicate函数。

以一个空String为例:

String emptyString = "";

现在我们可以通过提供适当的Predicate lambda函数来检查它的状态:

assertThat(emptyString)
  .matches(String::isEmpty);

4. 总结

在AssertJ系列文章的最后一章,我们探讨了所有高级的AssertJ Java 8功能,至此,该系列文章已全部介绍完毕。

所有示例代码可以在GitHub项目中找到。