2012-03-17 36 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