首先,請注意IterableSubject.containsExactly()
斷言輸入,這意味着 「正好包含所提供的對象或失敗」。 - 即使你可以在這裏傳遞Matcher
對象 - 我們斷言該列表恰好包含一個ExpectedType
實例。無論是現有的答案正確執行是不變的(而不是heenenee的方法,斷言的ExpectedType
一個實例,任何數量的其他實例的,和你的解決方案斷言列表包含的ExpectedType
實例的任何數量的)。當我讀到你的問題時,你打算聲明一個確切的屬性,但不管這表明接受的解決方案存在問題 - 它可能會意外地導致你不打算做出的斷言。
當我碰上這樣的真理API的限制,第一件事我總是試圖簡單地分裂主張成單獨的步驟。這通常證明書寫容易,易於閱讀,並且通常可以防止錯誤。可以理解的是,人們經常試圖尋找優雅的單線隊員,但一般來說,連續斷言沒有任何問題。
很難在這裏擊敗策略:
assertThat(ls).hasSize(1);
assertThat(Iterables.getOnlyElement(ls)).isInstanceOf(String.class);
如果可迭代不是大小爲1,我們會得到一個錯誤告訴我們,(隨着迭代的內容)。如果是,我們斷言唯一的元素是String
的一個實例。完成!
對於ň實例一般情況下,代碼也不可否認變得有點混亂,但它仍然是合理的。我們只是用assertWithMessage()
包括有關在isInstanceOf()
斷言名單的附加背景:
assertThat(ls).hasSize(n);
for (int i = 0; i < ls.size(); i++) {
assertWithMessage("list: %s - index: %s", ls, i)
.that(ls.get(i)).isInstanceOf(String.class);
}
這既是更具可讀性和比實現自己的自定義Subject
更清楚正確的。
由於Truth 0.29你可以做的更好使用 「Fuzzy Truth」 AKA Correspondence
。這允許您基本上描述集合的一些轉換,然後斷言該轉換的結果。在這種情況下,我們將創建一個INSTANCEOF_CORRESPONDENCE
:
private static final Correspondence<Object, Class<?>> INSTANCEOF_CORRESPONDENCE =
new Correspondence<Object, Class<?>>() {
@Override
public boolean compare(@Nullable Object actual, @Nullable Class<?> expected) {
return expected.isInstance(actual);
}
@Override
public String toString() {
return "is instanceof";
}
};
現在你可以寫一個漂亮的單行!
assertThat(ls).comparingElementsUsing(INSTANCEOF_CORRESPONDENCE)
.containsExactly(String.class);
這種方法在自定義對象的一大好處是它更可擴展的 - 如果你決定做一個不同的斷言Correspondence
實現並不需要改變,只是你的斷言:
assertThat(ls).comparingElementsUsing(INSTANCEOF_CORRESPONDENCE)
.doesNotContain(Integer.class);
也有tentative plans支持方法引用和lambda表達式與.comparingElementsUsing()
,這樣你就可以寫類似:
assertThat(ls).comparingElementsUsing((o, c) -> c.isInstance(o), "is instanceof")
.containsExactly(String.class);
的問題是真實的只要'IterableSubject'上的Truth'contains'動詞檢查元素的相等性。而「Matcher」不是'ExpectedType'。感謝您的回答(最終接受)。 – rds
請注意,您的'containsExactlyOneInstanceOf()'與['IterableSubject.containsExactly()'](https://google.github.io/truth/api/latest/com/google/common/truth/)行爲不同IterableSubject.html#containsExactly-java.lang.Object ...-) - 真理的方法需要完全給定的對象,沒有別的。 – dimo414