2

这个老问题的答案建议 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 代码并不关心多重性——上面的两个断言都会通过。

4

6 回答 6

2

GuavaMultiset旨在有效地跟踪元素的多次出现。

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

然后你有多次出现xif multiset.count(x) > 1

于 2012-02-08T23:28:39.313 回答
1
assertEquals(2, Collections.frequency(list, 1));
assertEquals(1, Collections.frequency(list, 2));

当然,如果你愿意,你可以使用 Hamcrest 表示法。

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

谢谢你的问题,否则我不会想到这个:-)

于 2012-02-11T02:28:02.170 回答
0

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

  • 将集合复制到新列表
  • 对于每个必须存在的元素,测试它是否存在,并将其从列表中删除
  • 如果您想检查一个对象是否没有更多实例,那么对于每个元素,测试它是否不再在列表中。
于 2012-02-08T08:16:46.350 回答
0

也许这只是我,但似乎HashMap是你的朋友。我错过了什么吗?

于 2012-02-08T08:22:36.557 回答
0

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

Collections.sort(list);

进而:

assertEquals(Arrays.asList(1, 1, 2), list);
于 2012-02-08T08:22:42.870 回答
0

您可以使用 Guava 的 Multimap,它基本上是键映射 -> 值列表。在这种情况下,您不太关心值列表,而是关心它的大小。您将从列表中创建以下多图:

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

那么你就可以

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

这确保您的原始列表中恰好有两个“1”。

如果您不想依赖 Guava,只需为每个数字创建一个映射到其计数,这需要更多的簿记,但总体上仍然非常简单。

于 2012-02-08T18:27:25.317 回答