Hamcrest 中 hasItems()、contains() 和 containsInAnyOrder() 之間的差異
一、簡介
Hamcrest 是一個以 Java 編寫匹配器物件的流行框架,提供了一個定義匹配條件的表達方式。像hasItems() 、 contains()和containsInAnyOrder()這樣的匹配器允許我們斷言集合中元素的存在和順序。在本教程中,我們將深入研究每個匹配器的用途、它們的差異以及何時使用它們。
2. 元素排序
在本節中,我們將探討hasItems() 、 contains()和containsInAnyOrder()如何處理集合中元素的順序。
2.1. hasItems()
hasItems()匹配器旨在檢查集合是否包含特定元素,而不關心它們的順序:
List<String> myList = Arrays.asList("apple", "banana", "cherry");
assertThat(myList, hasItems("apple", "cherry", "banana"));
assertThat(myList, hasItems("banana", "apple", "cherry"));
2.2. containsInAnyOrder()
與hasItems()類似, containsInAnyOrder()不考慮元素順序。它只關心指定的項目是否存在於集合中,而不管它們的順序如何:
assertThat(myList, containsInAnyOrder("apple", "cherry", "banana"));
assertThat(myList, containsInAnyOrder("banana", "apple", "cherry"));
2.3. contains()
相反, contains()匹配器是順序敏感的。它會驗證集合是否包含與提供的順序相同的確切指定項目:
assertThat(myList, contains("apple", "banana", "cherry"));
assertThat(myList, not(contains("banana", "apple", "cherry")));
第一個斷言通過,因為元素的順序完全匹配。在第二個斷言中,我們使用not()匹配器,它期望myList不包含嚴格順序的元素。
3. 精確的元素計數
在本節中,我們將討論hasItems() 、 contains()和containsInAnyOrder()如何處理集合中元素的確切數量。
3.1. hasItems()
hasItems()匹配器不要求集合具有精確的元素計數。它側重於確保特定項目的存在,而不對訂單或集合大小施加嚴格要求:
assertThat(myList, hasItems("apple", "banana"));
assertThat(myList, hasItems("apple", "banana", "cherry"));
assertThat(myList, not(hasItems("apple", "banana", "cherry", "date")));
在第一個斷言中,我們驗證myList包含「 apple 」和「 banana 」。由於這兩項都存在,因此斷言通過。類似地,第二個斷言檢查清單中是否存在“ apple ”、“ banana ”和“ cherry ”,因此它也通過了。
然而,第三個斷言包含一個額外的元素“ date ”,它不在myList中。結果, not()匹配器回傳成功。這說明,雖然hasItems()可以靈活地驗證元素是否存在,但如果在集合中發現超出指定範圍的額外項目,它會標記一個斷言。
3.2. containsInAnyOrder()
雖然hasItems()至少允許某些指定的項目,但containsInAnyOrder()匹配器要求集合包含清單中的所有項目。無論順序如何,只要所有指定的項目都存在,斷言就會通過:
assertThat(myList, containsInAnyOrder("apple", "banana", "cherry"));
assertThat(myList, not(containsInAnyOrder("apple", "banana")));
在第一個斷言中,我們驗證myList包含任意順序的「 apple 」、「 banana 」和「 cherry 」。由於所有指定的項目都存在於myList中,因此斷言通過。
第二個斷言檢查“ apple ”和“ banana ”,但省略“ cherry ”。在這裡,我們期望not() t成功,因為myList必須與指定元素完全匹配,包括此測試資料中缺少的「 cherry 」。
3.3. contains()
與containsInAnyOrder()類似, contains()匹配器也要求集合具有精確的元素計數,但按指定的順序:
assertThat(myList, contains("apple", "banana", "cherry"));
assertThat(myList, not(contains("apple", "banana")));
與containsInAnyOrder()類似,第二個斷言期望not()匹配器成功,因為測試資料中缺少「 cherry 」元素。
4. 處理重複項
在處理可能包含重複元素的集合時,必須了解hasItems() 、 contains()和containsInAnyOrder()的行為。
4.1. hasItems()
hasItems()匹配器不關心重複元素的存在。它只是檢查指定項目是否存在,無論它們是否重複:
List<String> myListWithDuplicate = Arrays.asList("apple", "banana", "cherry", "apple");
assertThat(myListWithDuplicate, hasItems("apple", "banana", "cherry"));
在此斷言中,我們驗證myListWithDuplicate包含「 apple 」、「 banana 」和「 cherry 」。 hasItems()匹配器檢查指定項目是否存在並忽略任何重複項。由於所有指定的項目都存在於列表中,因此斷言通過。
4.2. containsInAnyOrder()
類似地, containsInAnyOrder()不強制元素的排序。但是,它確保所有指定的項目都存在,無論是否重複:
assertThat(myList, containsInAnyOrder("apple", "banana", "cherry", "apple"));
assertThat(myListWithDuplicate, not(containsInAnyOrder("apple", "banana", "cherry")));
在這種情況下,第二個斷言測試資料中缺少「 apple 」重複元素,因此not()匹配器回傳成功。
4.3. contains()
另一方面, contains()匹配器需要精確匹配,包括元素的順序和精確計數。如果存在重複項但不是預期的,則斷言失敗:
assertThat(myList, not(contains("apple", "banana", "cherry")));
在此斷言中,測試資料中缺少「 apple 」重複元素,因此not()匹配器傳回成功。
5. 總結
讓我們總結一下這些匹配器之間的主要區別:
| 匹配器 | 命令 | 精確計數 | 處理重複項 | 目的 |
|---|---|---|---|---|
hasItems() |
不 | 不 | 忽略重複項 | 檢查指定元素是否存在,順序無關緊要 |
containsInAnyOrder() |
不 | 是的 | 需要精確的元素 | 檢查確切的元素,順序並不重要 |
contains() |
是的 | 是的 | 需要元素的精確序列 | 檢查確切的序列和確切的元素 |
六,結論
在本文中,我們探討了hasItems() 、 contains()和containsInAnyOrder()之間的差異。當我們只關心集合至少包含指定的項目(無論其順序如何)時,我們使用hasItems()**如果集合必須包含所有指定的項目,但順序無關緊要,我們可以使用containsInAnyOrder().**但是,如果集合必須按照提供的順序包含確切的指定項目,我們應該使用contains().
與往常一樣,範例的原始程式碼可在 GitHub 上取得。