断言集合在Java中有多个项目实例?

时间:2012-02-08 08:07:18

标签: java unit-testing junit assert hamcrest

this old question的答案建议Hamcrest在集合上声明。

如果我想断言一个集合有多个对象实例会怎么样?

list = newArrayList();
list.add(1);
list.add(1);
list.add(2);
assertThat(list, hasItems(1, 2, 2)); // This should fail
assertThat(list, hasItems(1, 2, 1)); // This should pass

我尝试的hamcrest代码并不关心多重性 - 上面的两个断言都会传递。

6 个答案:

答案 0 :(得分:2)

Guava的Multiset旨在有效地跟踪多个元素的出现。

Multiset<E> multiset = HashMultiset.create(collection);

然后,如果x,您会多次出现multiset.count(x) > 1

答案 1 :(得分:1)

assertEquals(2, Collections.frequency(list, 1));
assertEquals(1, Collections.frequency(list, 2));

当然,如果你愿意,可以在这上面使用Hamcrest符号。

优势是其他一些答案的多重优势:您可能不是该集合的所有者,因此您可能无法控制要使用的实现。此外,您不限于可以使用此技术的Collection(List,Set等)类型。

感谢您提出这个问题,我不会想到这个: - )

答案 2 :(得分:0)

自己写另一个断言。这个断言可以使用以下技术:

  • 将该集合复制到新列表
  • 对于必须存在的每个元素,测试是否存在,并将其从列表中删除
  • 如果你想检查没有更多的对象实例,那么对于每个元素,测试它不再在列表中。

答案 3 :(得分:0)

也许只是我,但似乎HashMap是你的朋友。我想念一下吗?

答案 4 :(得分:0)

我能想到的最简单的技术是首先对列表进行排序,然后使用相等比较:

Collections.sort(list);

然后:

assertEquals(Arrays.asList(1, 1, 2), list);

答案 5 :(得分:0)

你可以使用Guava的Multimap,它基本上是一个键映射 - &gt;价值清单。在这种情况下,您不必关心值列表,而是它的大小。您可以从列表中创建以下多图:

1 -> [1, 1]
2 -> [2]

然后你可以

Assert.assertEquals(2, map.get(1).size());

确保原始列表中只有两个“1”。

如果您不想依赖Guava,只需创建一个每个数字的地图到它的数量,这需要更多的簿记,但总体来说还是非常简单。