走進Java接口測試之流式斷言庫AssertJ

      網友投稿 1193 2025-04-01

      前言

      AssertJ簡介

      AssertJ使用

      導包

      入門使用

      對象斷言

      布爾斷言

      Iterable/Array斷言

      字符斷言

      類斷言

      文件斷言

      Double/Float/Integer斷言

      InputStream斷言

      Map斷言

      Throwable 斷言

      描述斷言

      前言

      AssertJ簡介

      AssertJ使用

      導包

      入門使用

      對象斷言

      布爾斷言

      Iterable/Array斷言

      字符斷言

      類斷言

      走進Java接口測試之流式斷言庫AssertJ

      文件斷言

      Double/Float/Integer斷言

      InputStream斷言

      Map斷言

      Throwable 斷言

      描述斷言

      小結

      前言

      在設計自動化接口 Cases 時,遵守的核心原則是3A(Arrange-> Actor ->Assert)原則;

      斷言工具是否強大直接影響到用例的執行效率,本文將介紹目前主流的一種流式斷言神器:AssertJ。

      AssertJ簡介

      什么是流式,常見的斷言器一條斷言語句只能對實際值斷言一個校驗點,而流式斷言器,支持一條斷言語句對實際值同時斷言多個校驗點,簡單理解,即 AssertJ 斷言是可以串接的。

      AssertJ 是一個 Java 庫,為 JDK 標準類型提供斷言,可以與 JUnit,TestNG 或任何其他測試框架一起使用。

      不同的 AssertJ 主要版本依賴于不同的 Java 版本:

      AssertJ 3.x 需要 Java 8或更高版本

      AssertJ 2.x 需要 Java 7或更高版本

      AssertJ 1.x 需要 Java 6或更高版本

      請注意,AssertJ 3.x包含所有AssertJ 2.x功能,并添加了Java 8特定功能(如 lambdas 的異常斷言)

      AssertJ 支持如下模塊:

      Core:AssertJ core is a Java library that provides a fluent interface for writing assertions.

      Assertions generator:Use the Assertion Generator to create assertions specific to your own classes.

      Guava:AssertJ assertions for Guava provides assertions for Guava types like Multimap, Table, Optional, Range or ByteSource.

      Joda-Time:AssertJ assertions for Joda-Time provides assertions for Joda-Time types like DateTime and LocalDateTime.

      DB:AssertJ-DB provides assertions to test data in a database.

      Neo4j:Provides assertions for Neo4j 3 or higher.

      Swing:AssertJ Swing is a Java library that provides a fluent interface for functional Swing UI testing.

      官方網站上提供了所有模塊的詳細列表。

      地址:https://joel-costigliola.github.io/assertj/index.html

      讓我們從幾個例子開始,直接來自 AssertJ 的官方文檔:

      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使用

      導包

      SpringBoot 內置了 AssertJ,只需要導入 spring-boot-starter-test 依賴包

      org.projectlombok lombok true org.springframework.boot spring-boot-starter-test org.testng testng 6.14.3

      入門使用

      為了編寫一個斷言,你總是需要先將對象傳遞給 Assertions.assertThat() 方法,然后再按照實際的斷言進行操作。

      重要的是要記住,與其他一些庫不同,下面的代碼實際上并沒有斷言任何東西,并且永遠不會失敗測試:

      assertThat(anyRefenceOrValue);

      如果你使用IDE的代碼完成功能,由于其描述性非常強的方法,編寫AssertJ 斷言變得異常簡單。下圖就是它在Intellij IDEA 中的樣子:

      如圖所見,有許多可供選擇的上下文方法,并且這些方法僅適用于String類型。

      對象斷言

      可以以各種方式比較對象,以確定兩個對象的相等性或檢查對象的字段。

      @Data @Builder @NoArgsConstructor @AllArgsConstructor public class Dog { private String name; private Float weight; }

      讓我們看兩種方法,我們可以比較兩個對象的相等性。鑒于以下兩個Dog對象 fido和 fidosClone

      @Test(description = "對象斷言1") public void whenComparingReferences_thenNotEqual() { // 實例化兩個對象 Dog fidos= new Dog("fidos",5.14f); Dog fidosClone = new Dog("fidosClone",5.14f); // 斷言兩個對象引用 assertThat(fidos).isNotEqualTo(fidosClone); }

      isEqualTo() 是比較對象引用,所以會執行失敗。如果我們想要比較它們的內容,我們可以使用 isEqualToComparingFieldByFieldRecursively()

      @Test(description = "對象斷言2") public void whenComparingFields_thenEqual() { // 實例化兩個對象 Dog fido = new Dog("Fido", 5.15f); Dog fidosClone = new Dog("Fido", 5.15f); // 斷言兩個對象內容 assertThat(fido).isEqualToComparingFieldByFieldRecursively(fidosClone); }

      當通過字段比較執行遞歸字段時,Fido和fidosClone是相等的,因為一個對象的每個字段與另一個對象中的字段進行比較。

      還有許多其他斷言方法提供了比較和收縮對象以及檢查和斷言其字段的不同方法。具體請參閱官方的 AbstractObjectAssert API。

      布爾斷言

      真值測試有一些簡單的方法:

      isTrue()

      isFalse()

      舉個例子:

      @Test(description = "布爾斷言") public void whenisEmpty_isTrue() { // 實例化對象 Dog fido = new Dog("Fido", 5.15f); // 斷言字段是否為空 assertThat(fido.getName().isEmpty()).isTrue(); }

      Iterable/Array斷言

      對于 Iterable 或 Array,有多種方法可以斷言它們的內容是否存在。最常見的斷言之一是檢查 Iterable 或 Array 是否包含給定元素:

      或者如果 List 不為空:

      assertThat(list).isNotEmpty();

      或者如果 List 以給定字符開頭。例如“1”:

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

      如果要為同一對象創建多個斷言,可以輕松地將它們連接在一起。

      下面是一個斷言示例,它檢查提供的列表是否為空,包含“1”元素,不包含任何空值并包含元素序列“2”,“3”:

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

      當然,對于那些類型存在更多可能的斷言 。具體請參閱官方的AbstractIterableAssert API

      完整示例:

      @Test(description = "Iterable/Array斷言1") public void whenCheckingForElement_thenContains(){ List list = Arrays.asList("1", "2", "3"); // 斷言是否包含給定元素 assertThat(list).contains("1"); } @Test(description = "Iterable/Array斷言2") public void whenCheckingForElement_thenMultipleAssertions() { List list = Arrays.asList("1", "2", "3"); // 斷言list不為空 assertThat(list).isNotEmpty(); // 斷言list以給定字段開頭 assertThat(list).startsWith("1"); // 斷言list不包含null assertThat(list).doesNotContainNull(); // 多個斷言 assertThat(list).isNotEmpty().contains("1").startsWith("1").doesNotContainNull().containsSequence("2", "3"); }

      字符斷言

      字符類型的斷言主要涉及比較,甚至檢查給定字符是否來自 Unicode 表。

      下面是一個斷言示例,它檢查提供的字符是否不是 ‘a’,在 Unicode 表中,是否大于 ‘b’ 并且是小寫的:

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

      有關所有字符類型斷言的詳細列表,請參閱 AbstractCharacterAssertAPI

      完整示例:

      @Test(description = "字符斷言") public void whenCheckingCharacter_thenIsUnicode() { char someCharacter = 'c'; // 斷言字符是否不是 'a',在 Unicode 表中,是否大于 'b' 并且是小寫的 assertThat(someCharacter).isNotEqualTo('a').inUnicode().isGreaterThanOrEqualTo('b').isLowerCase(); }

      類斷言

      Class 類型的斷言主要是檢查其字段,類類型,注釋的存在和類的最終性。

      如果你想斷言Runnable類是一個接口,你需要簡單地寫:

      assertThat(Runnable.class).isInterface();

      或者如果你想檢查一個類是否可以從另一個類中分配:

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

      可以在 AbstractClassAssert API 中查看所有可能的類斷言。

      完整示例:

      @Test(description = "類斷言1") public void whenCheckingRunnable_thenIsInterface() { // 斷言Runnable類是一個接口 assertThat(Runnable.class).isInterface(); } @Test(description = "類斷言2") public void whenAssigningNSEExToException_thenIsAssignable(){ // 斷言一個類是否可以從另一個類中分配 assertThat(Exception.class).isAssignableFrom(NoSuchElementException.class); }

      文件斷言

      文件斷言都是關于檢查給定的文件實例是否存在,是目錄還是文件,具有某些內容,是否可讀或具有擴展名。

      在這里斷言的示例,該斷言檢查給定文件是否存在,是文件而不是目錄,可讀寫的:

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

      可以在 AbstractFileAssert API 中查看所有可能的類斷言。

      完整示例:

      @Test(description = "文件斷言") public void whenCheckingFile_then() throws IOException { final File someFile = File.createTempFile("aaa", "bbb"); someFile.deleteOnExit(); // 斷言文件是否存在,是文件而不是目錄,可讀寫的 assertThat(someFile).exists().isFile().canRead().canWrite(); }

      Double/Float/Integer斷言

      數字斷言都是關于比較給定偏移量內或沒有給定偏移量的數值。

      例如,如果要根據給定的精度檢查兩個值是否相等,我們可以執行以下操作:

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

      請注意,我們使用已導入的 withPrecision(雙偏移)輔助方法來生成偏移對象。

      有關更多斷言,請訪問 AbstractDoubleAssert API。

      InputStream斷言

      只有一個可用的 InputStream 特定斷言:

      hasSameContentAs(預期的 InputStream)

      使用方法:

      assertThat(given).hasSameContentAs(expected);

      完整示例:

      @Test(description = "InputStream斷言") public void whenCheckingIS_then() { InputStream given = new ByteArrayInputStream("foo".getBytes()); InputStream expected = new ByteArrayInputStream("foo".getBytes()); // 斷言是否預期的 InputStream assertThat(given).hasSameContentAs(expected); }

      Map斷言

      Map 斷言允許你分別檢查 Map 是否包含某些條目,條目集或鍵/值。

      你可以看到斷言的示例,該斷言檢查給定的Map是否為空,包含key “2”,不包含數字鍵“10”并包含條目:key:2,value:“a”:

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

      有關更多斷言,請參閱 AbstractMapAssert API。

      完整示例:

      @Test(description = "Map斷言") public void whenGivenMap_then() { Map map = Maps.newHashMap(2, "a"); // 斷言Map是否為空,包含key “2”,不包含key “10” 并包含元素:key:2,value:“a” assertThat(map).isNotEmpty().containsKey(2).doesNotContainKeys(10).contains(entry(2, "a")); }

      Throwable 斷言

      Throwable 的斷言允許例如:檢查異常的信息,蹤跡,原因檢查或者異常被拋出已驗證。

      讓我們看一下斷言示例,該斷言檢查是否拋出了給定的異常并且消息以“c”結尾:

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

      有關更多斷言,請參閱 AbstractThrowableAssert API。

      完整示例:

      @Test(description = "Throwable斷言") public void whenGivenException_then() { Exception ex = new Exception("abc"); // 斷言是否拋出了給定的異常并且消息以“c”結尾 assertThat(ex).hasNoCause().hasMessageEndingWith("c"); }

      描述斷言

      為了獲得更高的詳細級別,你可以為斷言創建動態生成的自定義描述。

      這樣做的關鍵是 as(String description,Object … args)方法。

      如果你定義這樣的斷言:

      assertThat(fidos.getWeight()) .as("%s's age should be equal to 5.15f") .isEqualTo(5.15f);

      這是運行測試時的結果:

      org.junit.ComparisonFailure: [%s's age should be equal to 5.15f] Expected :5.1[5]f Actual :5.1[4]f

      完整示例:

      @Test(description = "描述斷言") public void whenRunningAssertion_thenDescribed() throws Exception { Dog fidos= new Dog("fidos",5.14f); assertThat(fidos.getWeight()).as("%s's age should be equal to 5.15f").isEqualTo(5.15f); }

      小結

      在本文中,我們簡要探討了AssertJ 為核心Java類型提供最流行的流式斷言的使用方法。

      本文源碼:

      https://github.com/zuozewei/blog-example/tree/master/Java-api-test/07-assert/springboot-assertj-demo

      Java 自動化測試

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:軟件設計之——“高內聚低耦合
      下一篇:人工智能如何幫助制造商提高生產效率
      相關文章
      亚洲丁香色婷婷综合欲色啪| 久久久久一级精品亚洲国产成人综合AV区 | 亚洲大尺度无码专区尤物| 一本色道久久88亚洲综合| 亚洲av无码有乱码在线观看| 456亚洲人成在线播放网站| 久久狠狠爱亚洲综合影院| 久久久久亚洲AV成人片| 久久亚洲AV成人无码软件| 18gay台湾男同亚洲男同| 亚洲精品在线不卡| 亚洲女人18毛片水真多| 亚洲伊人久久大香线蕉啊| 激情综合亚洲色婷婷五月APP| 亚洲中文无码av永久| 国产精品亚洲午夜一区二区三区| 亚洲三级中文字幕| 狠狠色伊人亚洲综合网站色| 亚洲精品无码av片| 伊人久久亚洲综合影院| 亚洲成aⅴ人片久青草影院| 亚洲精品无码99在线观看| 亚洲日本在线观看视频| 亚洲人成网77777亚洲色| 亚洲精品无码久久一线| 亚洲国产一区在线| 亚洲精品一卡2卡3卡三卡四卡| 亚洲精品在线视频观看| 亚洲毛片基地日韩毛片基地| 久久精品国产99国产精品亚洲| 亚洲色少妇熟女11p| 亚洲成av人片在线天堂无| 小说区亚洲自拍另类| AV在线亚洲男人的天堂| 国产亚洲精品一品区99热| 亚洲午夜精品一区二区 | 亚洲国产成人久久精品大牛影视| 老牛精品亚洲成av人片| 国内精品99亚洲免费高清| 久久精品国产亚洲AV麻豆王友容| 亚洲综合综合在线|