AssertEquals 2列表忽略顺序
这应该是一个非常简单的问题,我相信。 但不知何故,我无法在Google中find答案。
假设我有2个string列表。 首先包含“stringA”和“stringB” ,第二个包含“stringB”和“stringA” (注意差异顺序)。 我想用JUnit来testing它们是否包含完全相同的string。
是否有任何断言忽略顺序的string的平等检查? 对于给定的例子org.junit.Assert.assertEquals抛出AssertionError
java.lang.AssertionError: expected:<[String A, String B]> but was:<[String B, String A]>
解决办法是首先对列表进行sorting,然后将它们传递给断言。 但是我希望我的代码尽可能简单和干净。
我使用Hamcrest 1.3 , JUnit 4.11 , Mockito 1.9.5 。
正如你提到你使用Hamcrest,我会select一个集合Matchers
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; import static org.junit.Assert.assertThat; public class CompareListTest { @Test public void compareList() { List<String> expected = Arrays.asList("String A", "String B"); List<String> actual = Arrays.asList("String B", "String A"); assertThat("List equality without order", actual, containsInAnyOrder(expected.toArray())); } }
您可以使用List.containsAll来检查第一个列表包含第二个列表中的每个元素,反之亦然。
assertTrue(first.size() == second.size() && first.containsAll(second) && second.containsAll(first));
这是一个避免二次复杂的解决scheme(多次迭代列表)。 这使用Apache Commons CollectionUtils类创build每个项目的映射到列表中的频率计数本身。 然后它简单地比较两个地图。
Assert.assertEquals("Verify same metrics series", CollectionUtils.getCardinalityMap(expectedSeriesList), CollectionUtils.getCardinalityMap(actualSeriesList));
我也只是发现了CollectionUtils.isEqualCollection,声称做正是在这里被要求…
请注意,Roberto Izquierdo的解决scheme通常具有二次复杂性。 HashSets上的解决scheme总是具有线性复杂性:
assertTrue(first.size() == second.size() && new HashSet(first).equals(new HashSet(second)));
您可以使用junt-addons jar中的ListAssert 。
ListAssert.assertEquals(yourList, Arrays.asList(3, 4, 5));
为了快速解决,我会检查两种方式:
assertTrue(first.containsAll(second)); assertTrue(second.containsAll(first));
并尝试与相同的元素数量不同的情况下(例如1,1,2和1,2,2),我没有得到误报。