我想檢查一個地圖是否包含特定的一組條目。允許包含不在expectedMap
中的其他條目。目前,我有以下斷言:Hamcrest測試地圖包含來自另一個地圖的所有條目
assertThat(expectedMap.entrySet(), everyItem(isIn(actualMap.entrySet())));
雖然這樣做的工作,它打印的失敗消息是混亂的,因爲預期和接受的論點已經從正常使用逆轉。有沒有更好的方法來寫它?
我想檢查一個地圖是否包含特定的一組條目。允許包含不在expectedMap
中的其他條目。目前,我有以下斷言:Hamcrest測試地圖包含來自另一個地圖的所有條目
assertThat(expectedMap.entrySet(), everyItem(isIn(actualMap.entrySet())));
雖然這樣做的工作,它打印的失敗消息是混亂的,因爲預期和接受的論點已經從正常使用逆轉。有沒有更好的方法來寫它?
hasItems
做你想做的,但以一種不明顯的方式。由於Hamcrest對匹配Iterable
的支持相對有限,因此您必須跳過一些環節。 (沒有詳細說明,這是由於Java泛型如何工作的變幻莫測 - 我將在稍後發佈一些更詳細的鏈接)。
(我假設您使用的是泛型,例如Map<String, String>
而不是簡單的Map
)。
在你有幾個選項的同時...
如果你是幸福的,使用在測試@SuppressWarnings("unchecked")
提出了警告/測試代碼:
assertThat(actualMap.entrySet(), (Matcher)hasItems(expectedMap.entrySet().toArray()));
說明:沒有超載的hasItems
需要Set
或Iterable
,但它會佔用一個數組。 Set.toArray()
返回Object[]
,它不會與assertThat
對actualMap.entrySet()
匹配 - 但是如果您擦除匹配器的聲明類型,它將會愉快地繼續。
如果你想,如果沒有警告編譯斷言,它變得醜陋 - 你需要的Set
複製到某種Iterable<Object>
(你可以不投),以匹配的對象:
assertThat(new HashSet<Object>(actualMap.entrySet()), hasItems(expectedMap.entrySet().toArray()));
但要完全誠實的,爲了清楚你幾乎肯定是最好關閉單獨斷言每個條目:
for (Entry<String, String> entry : expectedMap.entrySet()) {
assertThat(actualMap, hasEntry(entry.getKey(), entry.getValue()));
}
...或者你可以寫自己的匹配 - 有豐富的資源如何做到這一點在線在SO上。
是的,我問的一個原因是因爲我不滿意警告或演員。它很醜。我同意現在最好的選擇可能是最好的。我過去寫過一些匹配器,如果我需要再做一次,我會爲它寫一個。 –