AssertJ 教程

AssertJ 教程

本文学习AssertJ,一个开源的、社区驱动的测试库,可以写流畅的、丰富的Java测试断言,我们主要聚焦AssertJ-core提供的功能。

1. 概述

1.1. 依赖

首先需要增加相应依赖,Spring Boot默认已经加载。

<dependency>
    <groupId>org.assertj</groupId>
    <artifactId>assertj-core</artifactId>
    <version>3.4.1</version>
    <scope>test</scope>
</dependency>

该依赖仅包括基本的java断言,包括Java 8特性,如果需要使用高级断言,需要单独增加额外的模块。对于Java7及以前版本需要使用2.x.x版本。读者可以选择合适版本或最新版本。

1.2. 简介

AssertJ提供一组类和工具方法,可以很容易写出流畅、优美的断言方法:

  • Standard Java
  • Java 8
  • Guava
  • Joda Time
  • Neo4J and
  • Swing components

读者可以在其官网上查看所有有效模块。下面是从官网摘取的几个简单示例看看:

assertThat(frodo)
  .isNotEqualTo(sauron)
  .isIn(fellowshipOfTheRing);
 
assertThat(frodo.getName())
  .startsWith("Fro")
  .endsWith("do")
  .isEqualToIgnoringCase("frodo");
 
assertThat(fellowshipOfTheRing)
  .hasSize(9)
  .contains(frodo, sam)
  .doesNotContain(sauron);

上面示例仅为冰山一角,但可以让我们了解下AssertJ写断言的大致情况。

2. 实战学习

本节我们将集中于学习AssertJ并探索其可能性。引入相应依赖或jar包之后,应用仅需在测试类中增加一句静态导入语句:

import static org.assertj.core.api.Assertions.*;

2.1. 写断言

写断言首先需要传入测试对象至Assertions.assertThat()方法,然后跟上实际的断言方法。与其他库不同,下面代码没有实际断言任何内容,也永远不会产生失败的测试:

assertThat(anyRefenceOrValue);

如果利用IDE代码提示特性,写AssertJ断言将变得难以置信地容易,所有方法都是自描述的,下面截图来着IDEA:
在这里插入图片描述
我们看到有很多与字符串相关方法可以选择,下面看看这些API的详细应用。

2.2. 对象断言

对象可以使用多种方式进行比较,既可以两个对象进行比较也可以对象的字段进行比较。下面示例看Dog类的对象fido和fidosClone之间比较:

public class Dog { 
    private String name; 
    private Float weight;
     
    // standard getters and setters
}
 
Dog fido = new Dog("Fido", 5.25);
 
Dog fidosClone = new Dog("Fido", 5.25);

也可以使用下面断言进行比较:

assertThat(fido).isEqualTo(fidosClone);

该对象引用之间比较会失败。如果比较其内容,可以使用isEqualToComparingFieldByFieldRecursively()方法:

assertThat(fido).isEqualToComparingFieldByFieldRecursively(fidosClone);

当对两个对象fido和fidosClone进行按字段递归比较,两者是相等。有许多断言方法提供不同方式进行比较,还可以对其字段进行检查和断言。

2.3. 布尔比较

布尔比较函数:

  • isTrue()
  • isFalse()

示例如下:

assertThat("".isEmpty()).isTrue();

2.4. Iterable/Array断言

对于Iterable/Array有多种断言方法判断其内容是否存在。最常见的是判断是否存在给定元素:

List<String> list = Arrays.asList("1", "2", "3");
 
assertThat(list).contains("1");

或判断是否为空:

assertThat(list).isNotEmpty();

或如果List已给定元素开头:

assertThat(list).startsWith("1");

如果在一个对象上进行多个断言,可以很容易采用链接方式。下面示例首先检查列表是否为空,然后判断是否包括“1”元素,不包括空值,并且包括元素序列“2”、“3”:

assertThat(list)
  .isNotEmpty()
  .contains("1")
  .doesNotContainNull()
  .containsSequence("2", "3");

该类型还有很多其他可能的断言,读者可以自己查看官网文档。

2.5. 字符断言

字符类型断言一般涉及比较和检查字符是否来自Unicode表。请看实例:

assertThat(someCharacter)
  .isNotEqualTo('a')
  .inUnicode()
  .isGreaterThanOrEqualTo('b')
  .isLowerCase();

方法几乎都是自描述,不再解释。

2.7. 类断言

类断言一般检查其字段和类的类型,注解是否存在、是否为final类。如果判断Runnable类是否为接口:

assertThat(Runnable.class).isInterface();

或者判断一个类是否从另一个类赋值:

assertThat(Exception.class).isAssignableFrom(NoSuchElementException.class);

2.7. 文件断言

File断言检查文件实例是否存在,是目录或文件,有一定内容,是否可读,具有特定扩展名。
下面示例执行一些列检查:

assertThat(someFile)
  .exists()
  .isFile()
  .canRead()
  .canWrite();

2.8. 数值类型断言

数值类型包括Double/Float/Integer及其他类型。断言主要比较数值在一定偏移量之内或之外。举例,检查两个数值在一定精度范围内是否相等:

assertThat(5.1).isEqualTo(5, withPrecision(1d));

注意这里使用withPrecision(Double offset) 方法生成偏移量对象。

2.9. InputStream断言

流断言只有一个方法:
hasSameContentAs(InputStream expected),示例如下:

assertThat(given).hasSameContentAs(expected);

2.10. Map断言

Map断言主要检查map是否包括特定项(key,value对),或key和value单独比较。示例如下:

assertThat(map)
  .isNotEmpty()
  .containsKey(2)
  .doesNotContainKeys(10)
  .contains(entry(2, "a"));

2.11. Throwable断言

Throwable断言主要检查异常消息,栈跟踪,原因(cause)检查或验证。示例如下:

assertThat(ex).hasNoCause().hasMessageEndingWith("c");

3. 断言描述

为了更好描述断言,可以在断言中动态生成自定义描述,使用as方法,示例如下:

assertThat(person.getAge())
  .as("%s's age should be equal to 100", person.getName())
  .isEqualTo(100);

运行测试输出结果如下:

[tom's age should be equal to 100] expected:<100> but was:<27>

4. 总结

本文简要说明了AssertJ提供的各种断言方法,帮助我们更便捷地写各种测试断言,更多功能可参考官网。

发布了395 篇原创文章 · 获赞 761 · 访问量 143万+

猜你喜欢

转载自blog.csdn.net/neweastsun/article/details/104006208