我正在尝试比较 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
可变参数方法并直接提供值:
assertThat(actual.getList(), containsInAnyOrder("item1", "item2"));
(假设您的列表是 String
,而不是 Agent
,对于此示例。)
如果您真的想使用 List
的内容调用相同的方法:
assertThat(actual.getList(), containsInAnyOrder(expectedList.toArray(new String[expectedList.size()]));
如果没有这个,您将使用单个参数调用该方法并创建一个 Matcher
,该 Matcher
期望匹配一个 Iterable
,其中 每个元素 是一个 List
。这不能用于匹配 List
。
也就是说,您无法将 List<Agent>
与 Matcher<Iterable<List<Agent>>
匹配,而这正是您的代码所尝试的。
List<Long> actual = Arrays.asList(1L, 2L);
List<Long> expected = Arrays.asList(2L, 1L);
assertThat(actual, containsInAnyOrder(expected.toArray()));
@Joe 的答案的较短版本,没有多余的参数。
为了补充@Joe的回答:
Hamcrest 为您提供了三种主要的方法来匹配列表:
contains
检查是否匹配所有按顺序计算的元素,如果列表有更多或更少的元素,它将失败
containsInAnyOrder
检查是否匹配所有元素,顺序无关紧要,如果列表包含更多或更少的元素,则会失败
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...)
使用现有的 Hamcrest 库(从 v.2.0.0.0 开始),您必须在 Collection 上使用 Collection.toArray() 方法才能使用 containsInAnyOrder 匹配器。将其作为单独的方法添加到 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());
}
实际上,我最终将此方法添加到了我的自定义测试库中,并使用它来增加我的测试用例的可读性(由于更少的冗长)。
对于对象列表,您可能需要以下内容:
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任何帮助避免被抑制的警告将不胜感激。
确保列表中的 Object
已定义 equals()
。然后
assertThat(generatedList, is(equalTo(expectedList)));
作品。
要将两个列表与保留的顺序(严格顺序)进行比较,请使用。
assertThat(actualList, contains("item1","item2"));
如果我们想在没有特定顺序的情况下进行比较,可以使用以下命令
assertThat(collection, containsInAnyOrder("item1","item2"));
actualList
是否包含 contains
匹配器中的元素,如果元素的顺序不同,则会失败,如果它包含更多元素或缺少一个元素,也会失败。
不定期副业成功案例分享
containsInAnyOrder
要求 所有 元素都存在,因此第一个断言将失败。如果您想检查至少这些元素是否存在,请参阅hasItems
。actual.getList()
恰好包含"item1", "item3", "item2"
,则测试将通过,也许您想确保它仅包含列出的项目...在这种情况下,您可以在 containsInAnyOrder 之前使用assertThat(actual.getList().size(), equalTo(2));
,这样可以确保两个列表具有相同的内容。hasItems
。这里不需要额外的检查。请参阅上面对 Tim 的评论,以及 How do Hamcrest's hasItems, contains and containsInAnyOrder differ?*expectedList.toTypedArray()
)!