JUnit 4 compare Sets

如何简洁地断言 Collection元素的相等性,特别是 JUnit 4中的 Set

119298 次浏览

Hamcrest合作:

assertThat(s1, is(s2));

用简单的断言:

assertEquals(s1, s2);

注意: t 使用 混凝土集合类混凝土集合类的 equals ()方法

检查 这篇文章。一个例子从那里:

@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);
}

You can assert that the two Sets are equal to one another, which invokes the Set equals()方法.

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 );
}
}

如果两个 Set大小相同并且包含相同的元素,则此 @Test将通过。

一个特别有趣的例子是当你比较

   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()));

或者我可以一个元素一个元素地比较。

Apache commons to the rescue again.

assertTrue(CollectionUtils.isEqualCollection(coll1, coll2));

非常有效。我不知道为什么,但我发现,与集合下面的 assertEquals(coll1, coll2)并不总是工作。在这种情况下,我失败了,我有两个集合的集合支持。无论是 Hamcrest 还是 junit 都不会说收藏品是平等的,即使我知道它们确实是平等的。使用 CollectionUtils 可以很好地工作。

作为一个基于数组的附加方法... ... 您可以考虑在 junitx 中使用无序数组断言。虽然 Apache CollectionUtils 示例可以工作,但是还有一个可靠的断言扩展包:

我认为

ArrayAssert.assertEquivalenceArrays(new Integer[]{1,2,3}, new Integer[]{1,3,2});

方法将更具可读性和可调试性(所有集合都支持 Array () ,因此使用 ArrayAssert 方法应该很容易。

当然,这里的缺点是 junitx 是一个附加的 jar 文件或者 maven 条目..。

 <dependency org="junit-addons" name="junit-addons" rev="1.4"/>

如果您想检查 List 或 Set 是否包含一组特定的值(而不是将其与已有的集合进行比较) ,通常可以使用集合的 toString 方法:

String[] actualResult = calltestedmethod();
assertEquals("[foo, bar]", Arrays.asList(actualResult).toString());


List otherResult = callothertestedmethod();
assertEquals("[42, mice]", otherResult.toString());

This is a bit shorter than first constructing the expected collection and comparing it with the actual collection, and easier to write and correct.

(Admittedly, this is not a particularily clean method, and can't distinguish an element "foo, bar" from two elements "foo" and "bar". But in practice I think it's most important that it's easy and fast to write tests, otherwise many developers just won't without being pressed.)

使用 Hamcrest:

assertThat( set1, both(everyItem(isIn(set2))).and(containsInAnyOrder(set1)));

This works also when the sets have different datatypes, and reports on the difference instead of just failing.

我喜欢 Hans-Peter Störr 的解决方案... ... 但我认为它不完全正确。遗憾的是,containsInAnyOrder不接受 Collection的对象进行比较。所以它必须是 MatcherCollection:

assertThat(set1, containsInAnyOrder(set2.stream().map(IsEqual::equalTo).collect(toList())))

The import are:

import static java.util.stream.Collectors.toList;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertThat;