Hamcrest比较collections

我试图比较2个列表:

assertThat(actual.getList(), is(Matchers.containsInAnyOrder(expectedList))); 

但是想法

 java: no suitable method found for assertThat(java.util.List<Agent>,org.hamcrest.Matcher<java.lang.Iterable<? extends model.Agents>>) method org.junit.Assert.<T>assertThat(T,org.hamcrest.Matcher<T>) is not applicable (no instance(s) of type variable(s) T exist so that argument type org.hamcrest.Matcher<java.lang.Iterable<? extends model.Agents>> conforms to formal parameter type org.hamcrest.Matcher<T>) method org.junit.Assert.<T>assertThat(java.lang.String,T,org.hamcrest.Matcher<T>) is not applicable (cannot instantiate from arguments because actual and formal argument lists differ in length) 

我该怎么写呢?

如果你想断言这两个列表是相同的,不要使Hamcrest的事情复杂化:

 assertEquals(expectedList, actual.getList()); 

如果你真的打算执行一个命令不敏感的比较,你可以调用containsInAnyOrder varargs方法并直接提供值:

 assertThat(actual.getList(), containsInAnyOrder("item1", "item2")); 

(假设你的列表是String ,而不是Agent ,这个例子)

如果你真的想用一个List的内容调用同样的方法:

 assertThat(actual.getList(), containsInAnyOrder(expectedList.toArray(new String[expectedList.size()])); 

如果没有这个,你只用一个参数来调用这个方法,然后创build一个Matcher来匹配一个Iterable ,其中每个元素都是一个List 。 这不能用来匹配一个List

也就是说,您无法将List<Agent>Matcher<Iterable<List<Agent>> List<Agent>进行Matcher<Iterable<List<Agent>> ,这就是您的代码正在尝试的内容。

只有我想添加到@ Joe的答案是toArray()参数在这里是多余的,所以你可以写如下顺序不敏感的比较:

 List<Long> actual = Arrays.asList(1L, 2L); List<Long> expected = Arrays.asList(2L, 1L); assertThat(actual, containsInAnyOrder(expected.toArray())); 

使用现有的Hamcrest库(截至v2.0.0.0),您必须在您的Collection上使用Collection.toArray()方法才能使用containsInAnyOrder Matcher。 更好的办法是把这个作为一个单独的方法添加到org.hamcrest.Matchers:

 public static <T> org.hamcrest.Matcher<java.lang.Iterable<? extends T>> containsInAnyOrder(Collection<T> items) { return org.hamcrest.collection.IsIterableContainingInAnyOrder.<T>containsInAnyOrder((T[]) items.toArray()); } 

其实我最终将这种方法添加到我的自定义testing库,并使用它来提高我的testing用例的可读性(由于较less冗长)。

补充@ Joe的回答:

Hamcrest为您提供了三种匹配列表的主要方法:

contains检查是否匹配所有的元素,如果列表中有更多或更less的元素,则会失败

containsInAnyOrder检查是否匹配所有元素,如果列表包含更多或更less的元素,则顺序无关,将失败

hasItems只检查指定的对象,如果列表有更多,则无关紧要

hasItem只检查一个对象,如果列表有更多,则无关紧要

他们都可以收到一个对象的列表,并使用equals方法进行比较,或者可以与其他匹配器(如@borjab)混合使用:

 assertThat(myList , contains(allOf(hasProperty("id", is(7L)), hasProperty("name", is("testName1")), hasProperty("description", is("testDesc1"))), allOf(hasProperty("id", is(11L)), hasProperty("name", is("testName2")), hasProperty("description", is("testDesc2"))))); 

http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#contains(E …) http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html #containsInAnyOrder(java.util.Collection) http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#hasItems(T …)

对于列表的对象,你可能需要这样的东西:

 import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.beans.HasPropertyWithValue.hasProperty; import static org.hamcrest.Matchers.is; @Test @SuppressWarnings("unchecked") public void test_returnsList(){ arrange(); List<MyBean> myList = act(); assertThat(myList , contains(allOf(hasProperty("id", is(7L)), hasProperty("name", is("testName1")), hasProperty("description", is("testDesc1"))), allOf(hasProperty("id", is(11L)), hasProperty("name", is("testName2")), hasProperty("description", is("testDesc2"))))); } 

如果您不想检查对象的顺序,请使用containsInAnyOrder 。

PS任何帮助,以避免被suppresed的警告将非常感激。

确保列表中的Object在其上定义了equals() 。 然后

  assertThat(generatedList,is(equalTo(expectedList))); 

作品。

为了比较两个列表与保存顺序的使用,

 assertThat(actualList, contains("item1","item2"));