1. 概述

本文将重点介绍AssertJ与Guava相关的断言,并是AssertJ系列文章的第二篇。如果你对AssertJ的基本信息感兴趣,可以参考系列文章的第一篇:AssertJ简介

2. Maven依赖

为了在项目中使用AssertJ与Guava结合,你需要在pom.xml中添加以下依赖:

<dependency>
    <groupId>org.assertj</groupId>
    <artifactId>assertj-guava</artifactId>
    <version>3.0.0</version>
    <scope>test</scope>
</dependency>

你可以在这里找到最新版本:点击获取

需要注意的是,从3.0.0版本开始,AssertJ Guava依赖于Java 8AssertJ Core 3.x

3. Guava断言实战

AssertJ针对Guava类型提供了定制化的断言:ByteSourceMultimapOptionalRangeRangeMapTable

3.1. ByteSource断言

首先,创建两个临时文件:

File temp1 = File.createTempFile("bael", "dung1");
File temp2 = File.createTempFile("bael", "dung2");

然后从这些文件创建ByteSource实例:

ByteSource byteSource1 = Files.asByteSource(temp1);
ByteSource byteSource2 = Files.asByteSource(temp2);

现在我们可以写出如下断言:

assertThat(buteSource1)
  .hasSize(0)
  .hasSameContentAs(byteSource2);

3.2. Multimap断言

Multimap是一种可以为给定键关联多个值的地图。Multimap断言的工作方式与普通Map实现非常相似。

首先创建一个Multimap实例并添加一些条目:

Multimap<Integer, String> mmap = Multimaps
  .newMultimap(new HashMap<>(), Sets::newHashSet);
mmap.put(1, "one");
mmap.put(1, "1");

接着进行断言:

assertThat(mmap)
  .hasSize(2)
  .containsKeys(1)
  .contains(entry(1, "one"))
  .contains(entry(1, "1"));

此外,还有两个额外的断言,它们之间存在微妙的区别:

  • containsAllEntriesOf
  • hasSameEntriesAs.

让我们来看看这两个断言。首先定义几个映射:

Multimap<Integer, String> mmap1 = ArrayListMultimap.create();
mmap1.put(1, "one");
mmap1.put(1, "1");
mmap1.put(2, "two");
mmap1.put(2, "2");

Multimap<Integer, String> mmap1_clone = Multimaps
  .newSetMultimap(new HashMap<>(), HashSet::new);
mmap1_clone.put(1, "one");
mmap1_clone.put(1, "1");
mmap1_clone.put(2, "two");
mmap1_clone.put(2, "2");

Multimap<Integer, String> mmap2 = Multimaps
  .newSetMultimap(new HashMap<>(), HashSet::new);
mmap2.put(1, "one");
mmap2.put(1, "1");

如你所见,mmap1mmap1_clone包含完全相同的条目,但它们是不同类型的两个不同的Map对象。而mmap2包含一个共享给所有映射的单一条目。现在,以下断言为真:

assertThat(mmap1)
  .containsAllEntriesOf(mmap2)
  .containsAllEntriesOf(mmap1_clone)
  .hasSameEntriesAs(mmap1_clone);

3.3. Optional断言

Guava的Optional断言包括值存在检查和提取内部值的工具。

首先创建一个Optional实例:

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

然后可以检查值是否存在并断言Optional的内容:

assertThat(something)
  .isPresent()
  .extractingValue()
  .isEqualTo("something");

3.4. Range断言

Guava的Range类断言涉及检查范围的下限和上限,或者检查某个值是否在给定范围内。

首先定义一个简单的字符范围:

Range<String> range = Range.openClosed("a", "g");

现在可以测试:

assertThat(range)
  .hasOpenedLowerBound()
  .isNotEmpty()
  .hasClosedUpperBound()
  .contains("b");

3.5. Table断言

AssertJ针对表格的特定断言允许检查行数、列数以及单元格值的存在。

创建一个简单的Table实例:

Table<Integer, String, String> table = HashBasedTable.create(2, 2);
table.put(1, "A", "PRESENT");
table.put(1, "B", "ABSENT");

现在可以执行以下检查:

assertThat(table)
  .hasRowCount(1)
  .containsValues("ABSENT")
  .containsCell(1, "B", "ABSENT");

4. 总结

在本篇AssertJ系列文章中,我们探讨了所有与Guava相关的功能。

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