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提供的各種斷言方法,幫助我們更便捷地寫各種測試斷言,更多功能可參考官網。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章