Unit testing 在集合上对循环进行单元测试

Unit testing 在集合上对循环进行单元测试,unit-testing,Unit Testing,假设我有以下(Java)代码: 类MyObject{ 私人int演示; /*…其他属性*/ /*…能手,二传手*/ } 类TestMe{ 公共静态集合processAll(集合输入){ Set result=new HashSet(); 用于(最终MyObject条目:输入){ 结果。添加(过程(输入)); } 返回结果; } 私有静态MyObject进程(MyObject输入){ MyObject结果=新的MyObject(); result.setDemo(input.getDemo()+1

假设我有以下(Java)代码:

类MyObject{
私人int演示;
/*…其他属性*/
/*…能手,二传手*/
}
类TestMe{
公共静态集合processAll(集合输入){
Set result=new HashSet();
用于(最终MyObject条目:输入){
结果。添加(过程(输入));
}
返回结果;
}
私有静态MyObject进程(MyObject输入){
MyObject结果=新的MyObject();
result.setDemo(input.getDemo()+1);
返回结果;
}
}
现在我想为这段代码编写一个测试。为process方法编写一个测试是很容易的。结果对象的“demo”值应该比输入对象大一个,并且输入对象没有更改。由于该方法是私有的,我希望无论如何都避免测试该方法

但是,我想测试processAll方法是否适用于空集合(easy)、集合中的一个条目(easy)以及集合中的多个元素(这是我的问题)

因为结果是一个集合,processAll结果中元素的顺序是未定义的,我不能简单地测试第一个元素是X,第二个元素是Y。我不能使用一些简单的
actual.containsAll(预期)和&expected.containsAll(实际)
magic,因为如果MyObject只检查标识,则使用equals方法(改变这一点是没有意义的)

我试图通过编写自己的比较器对processAll的输入和输出进行排序,将所有元素添加到SortedSet,然后在这两个集合上进行迭代,假设output-1的demo属性等于输入。但我发现我的断言代码变大了,很难理解


有什么“最佳实践”吗-处理这种情况的方法?

您提到了使用
containsAll
的困难。这不是检查集合内容的唯一方法。您还可以遍历其成员,在找到预期对象时设置一个标志,然后在循环检查完所有标志是否都已设置后再进行设置。

正在进行单元测试

您可以对“set为空”的情况进行简单测试

您可以对“set contains a single element”案例进行简单测试。该测试涵盖转换和循环

您可以进行一个简单的测试,检查输出的大小是否等于输入的大小


现在,您的所有代码都包含在内,额外的测试只会确保您的代码不会对超过1个元素的集合执行不同的操作。但出现这种问题的概率非常接近于0。因此,这样复杂的测试不会添加任何有价值的内容,但很难理解和维护。即使您进行了测试对于10个元素,它不会涵盖代码对包含11个元素的集合执行不同操作的情况(也是极不可能的情况)。

如果您确实需要复杂的断言逻辑,您可能需要考虑以Hamcrest的形式编写该逻辑,而不是直接将测试代码弄乱

可能是Hamcrest提供的其中一个标准对您很有用,尽管考虑到标准集比较技术的困难,这似乎不太可能

如果您使用的是JUnit的最新版本,它可能包括这些,您可以使用JUnit方法