2012-03-17 111 views
3

我如何測試兩個使用JUnit的迭代器的相等性?測試兩個迭代器是否相等?

有沒有內置的方法,或只是通過比較每個元素?

感謝, 斯利拉姆

+0

中描述的assertThat(a, is(b))我不認爲我曾經考慮過這個問題。 – 2012-03-17 19:34:55

+1

請記住,'Iterator'可以是任意長的(甚至是無限的)。如果有一種內置的方法用於測試兩個迭代器的相等性,並且它在合理的時間內運行,我可以用它來生成有趣且可發佈的數學證明。 – emory 2012-03-17 19:54:57

+0

此外,測試內容是一種破壞性操作。 – OrangeDog 2017-07-14 15:18:46

回答

1

有沒有一種理智的方式來測試Iterators的平等。

如果在這方面瘋狂是一個選項,你可能想深入研究你正在測試的特定迭代器類型的實現,並使用反射來訪問私人東西並比較它(我相信,有足夠的分析源代碼,例如,您會發現需要保持兩個ListIterator相等的內容)。

或者如果它是你自己的迭代器類型,那麼導出一些變量來幫助你,並使用它們而不是反射。

迭代遍歷和比較元素只是一個很弱的保證,因爲你可以迭代你的集合的一個副本,這意味着迭代器看起來是一樣的,但不是。

只是不這樣做。

+0

>「...,因爲你可以迭代你的集合的一個克隆,這意味着迭代器看起來是一樣的,但不是。」< 你是什麼意思的「克隆」?我看到開發人員在處理迭代器時可能有一個「底層集合」的問題,但迭代器可以不存在「集合」和「可迭代」存在。在測試場景中,檢查迭代器的行爲可能是有意義的,因爲有時你只能無奈地處理給定的API,無論它設計得有多好。 – 2016-11-16 09:38:18

+0

您可以準確複製原始集合和兩個迭代器,指向同一位置的每個迭代器。如果你通過這些迭代器比較容器值,你會認爲迭代器是*相等的,但實際上它們指向不同的集合。 – Irfy 2016-11-17 09:23:00

+0

好的,所以你的想法是,當比較迭代器時,如果它們的底層集合是相同的,那麼你只希望它們是平等的,這當然意味着這樣的底層集合首先存在。 我不認爲這是必要的,因爲即使官方Javadoc將Iterator定義爲「集合上的迭代器」(小寫'c'),「Iterator」接口也提供沒有辦法訪問收藏,但只有一個接一個的元素。因此,只給定一個「Iterator」,當定義相等時,我們甚至不可能談論底層集合。 – 2016-11-29 10:36:36

5

你不能(和不需要)測試迭代器的平等,只有底層的集合。要做到這一點,您可以迭代兩者,並按照您猜測的順序依次比較每對元素。請注意,這有效地消耗了至少一個迭代器。結果取決於測試開始時迭代器的狀態,所以這種方法很脆弱。因此,最好是掌握底層集合,並儘可能地直接測試它們是否相等(使用它們的方法equals)。

爲什麼你會想要測試兩個迭代器的相等性?如果你解釋你的具體問題,我們可能會提供一個更好的選擇。

+1

可能不一定有潛在的集合。如果有潛在的收藏品,它可能是無限的。 – emory 2012-03-17 19:56:15

+1

我有一個函數返回一個Iterator類型。 http://stackoverflow.com/questions/9747291/does-a-getter-with-a-different-return-type-qualify-as-a-getter。我正在測試這個。 – sriram 2012-03-17 20:20:16

+1

@emory,好點,儘管這些聽起來更像是功能語言的例子,而不是Java。 – 2012-03-17 21:20:24

0

除了對象身份之外,沒有「經典」的平等概念,因爲它們在「最差」類型中是可變的。

在JUnit場景中,最好將值next()返回到列表中,例如,使用番石榴的ImmutableList.copyOf(Iterator<T>),然後按this SO answer