你如何简洁地断言Collection
元素的平等,特别是JUnit 4中的Set
?
答案 0 :(得分:95)
您可以声明两个Set
彼此相等,这会调用Set
equals()
method。
public class SimpleTest {
private Set<String> setA;
private Set<String> setB;
@Before
public void setUp() {
setA = new HashSet<String>();
setA.add("Testing...");
setB = new HashSet<String>();
setB.add("Testing...");
}
@Test
public void testEqualSets() {
assertEquals( setA, setB );
}
}
如果两个@Test
的大小相同且包含相同的元素,则Set
将会通过。
答案 1 :(得分:39)
Apache又再次拯救。
assertTrue(CollectionUtils.isEqualCollection(coll1, coll2));
像魅力一样工作。我不知道为什么,但我发现使用集合时,以下assertEquals(coll1, coll2)
并不总是有效。在我失败的情况下,我有两个由Sets支持的集合。即使我确定他们是肯定的,所以无论是汉克雷斯特还是君子都不会说收藏品是平等的。使用CollectionUtils它可以很好地工作。
答案 2 :(得分:12)
答案 3 :(得分:7)
一个特别有趣的案例是比较
java.util.Arrays$ArrayList<[[name,value,type], [name1,value1,type1]]>
和
java.util.Collections$UnmodifiableCollection<[[name,value,type], [name1,value1,type1]]>
到目前为止,我看到的唯一解决方案是将它们都改为集合
assertEquals(new HashSet<CustomAttribute>(customAttributes), new HashSet<CustomAttribute>(result.getCustomAttributes()));
或者我可以逐个元素地比较它们。
答案 4 :(得分:4)
作为基于数组的附加方法...您可以考虑在junitx中使用无序数组断言。尽管Apache CollectionUtils示例可行,但也存在一些固定的断言扩展:
我认为
ArrayAssert.assertEquivalenceArrays(new Integer[]{1,2,3}, new Integer[]{1,3,2});
方法对您来说更具可读性和可调试性(所有Collections都支持toArray(),因此使用ArrayAssert方法应该很容易。
当然,这里的缺点是,junitx是一个额外的jar文件或maven条目......
<dependency org="junit-addons" name="junit-addons" rev="1.4"/>
答案 5 :(得分:2)
检查this article。那里有一个例子:
@Test
public void listEquality() {
List<Integer> expected = new ArrayList<Integer>();
expected.add(5);
List<Integer> actual = new ArrayList<Integer>();
actual.add(5);
assertEquals(expected, actual);
}
答案 6 :(得分:1)
使用Hamcrest:
assertThat( set1, both(everyItem(isIn(set2))).and(containsInAnyOrder(set1)));
当集合具有不同的数据类型时,这也有效,并报告差异而不是仅失败。
答案 7 :(得分:0)
如果要检查列表或集合是否包含一组特定值(而不是将其与现有集合进行比较),通常收集的toString方法很方便:
String[] actualResult = calltestedmethod();
assertEquals("[foo, bar]", Arrays.asList(actualResult).toString());
List otherResult = callothertestedmethod();
assertEquals("[42, mice]", otherResult.toString());
这比首先构建预期集合并将其与实际集合进行比较要短一些,并且更容易编写和更正。
(不可否认,这不是一个特别简洁的方法,并且不能将元素“foo,bar”与两个元素“foo”和“bar”区分开来。但在实践中我认为最简单的是它简单快速编写测试,否则许多开发人员不会没有被按下。)
答案 8 :(得分:0)
我喜欢Hans-PeterStörr的解决方案......但我认为这不太正确。遗憾的是,containsInAnyOrder
不接受Collection
个objetc来比较。所以它必须是Collection
的{{1}}:
Matcher
导入是:
assertThat(set1, containsInAnyOrder(set2.stream().map(IsEqual::equalTo).collect(toList())))