在jUnit测试中,我想根据name
列从数据库中获取一些行。然后我想测试我得到的行有我期望的名字。我有以下内容:
Set<MyClass> typesToGet = MyClassFactory.createInstances("furniture",
"audio equipment");
Collection<String> namesToGet = Collections2.transform(typesToGet,
new NameFunction<MyClass, String>());
List<MyClass> typesGotten = _svc.getAllByName(typesToGet);
assertThat(typesGotten.size(), is(typesToGet.size()));
Collection<String> namesGotten = Collections2.transform(typesGotten,
new NameFunction<ItemType, String>());
assertEquals(namesToGet, namesGotten); // fails here
我目前失败了:
java.lang.AssertionError:expected:com.google.common.collect.Collections2 $ TransformedCollection&lt; [audio equipment,furniture]&gt;但是:com.google.common.collect.Collections2 $ TransformedCollection&lt; [audio equipment,furniture]&gt;
那么什么是最干净,最简洁的方法来测试我从name
列匹配我想要的名称的数据库中获取行?我可以有一个for
循环遍历并检查一个列表中的每个名称是否存在于另一个列表中,但我希望更简洁。类似下面的伪代码会很好:
List<MyClass> typesGotten = ...;
["furniture", "audio equipment"].equals(typesGotten.map(type => type.getName()))
答案 0 :(得分:15)
您可以使用containsAll()
两次来检查您是否有任何缺失值或任何意外值。
assertTrue(namesToGet.containsAll(namesGotten));
assertTrue(namesGotten.containsAll(namesToGet));
但是,如果您决定使用List
或Set
而不是Collection
,则接口合同会指定List
等于另一个List
({ {3}})same for Set
。
将指定对象与此列表进行比较以获得相等性。当且仅当指定的对象也是列表时,返回
true
,两个列表具有相同的大小,并且两个列表中的所有对应元素对都相等。 (如果(e1==null ? e2==null : e1.equals(e2))
,则两个元素e1和e2相等。)换句话说,如果两个列表包含相同顺序的相同元素,则它们被定义为相等。此定义确保equals方法在List
接口的不同实现中正常工作。
<强>资源:强>
答案 1 :(得分:6)
如果您希望它们包含相同的元素,但不一定按相同的顺序排列,那么只需复制它们ImmutableSet
并检查这些集合是否相等。如果您希望它们具有相同的顺序,则执行ImmutableList
次复制并检查它们是否相同。
Collection
根本没有任何平等概念。
答案 2 :(得分:6)
写这样一个断言的最新和最具表现力的方式是使用Hamcrest匹配器:
assertThat(namesGotten, containsInAnyOrder(namesToGet))
答案 3 :(得分:3)
Guava有一种方法可以很好地传达您想要获得的概念:symmetricDifference。如果symmetricDifference为空,则集合相等。
assetTrue(Sets.symmetricDifference(namesToGet, namesGotten).isEmpty());
然而,它可能不是“最便宜的”,因为它执行并集,交集和差异操作。您还可以检查集合是否大小相同 - 如果不相同,则它们不包含相同的元素,如果它们是,则可以验证(非对称)difference是否为空。
assertEquals(namesToGet.size(), namesGotten.size());
assertTrue(Sets.difference(namesToGet, namesGotten));