如果给定的集合包含给定顺序的给定项目,如何使用Hamcrest进行检查?我试过hasItems
,但它只是忽略了顺序。
List<String> list = Arrays.asList("foo", "bar", "boo");
assertThat(list, hasItems("foo", "boo"));
//I want this to fail, because the order is different than in "list"
assertThat(list, hasItems("boo", "foo"));
答案 0 :(得分:49)
您可以使用contains
匹配器,但您可能需要使用最新版本的Hamcrest。该方法检查订单。
assertThat(list, contains("foo", "boo"));
如果订单对您无关紧要,您也可以尝试使用containsInAnyOrder
。
这是contains
匹配器的代码:
public static <E> Matcher<Iterable<? extends E>> contains(List<Matcher<? super E>> itemMatchers)
{
return IsIterableContainingInOrder.contains(itemMatchers);
}
答案 1 :(得分:7)
要检查集合中是否包含预期(给定)顺序的项目,您可以使用Hamcrest的containsInRelativeOrder
方法。
来自javadoc:
为Iterable创建匹配器,在单次传递时匹配 检查的Iterable产生一系列包含项目的项目 逻辑上等于指定项目中的相应项目 相同的相对顺序例如:assertThat(Arrays.asList(&#34; a&#34;, &#34; b&#34;,&#34; c&#34;,&#34; d&#34;,&#34; e&#34;),containsInRelativeOrder(&#34; b&#34;,&# 34; d&#34;))
Java Hamcrest 2.0.0.0的实际值。
希望这有帮助。
答案 2 :(得分:2)
您需要实现自定义匹配器,类似这样
class ListMatcher extends BaseMatcher {
String[] items;
ListMatcher(String... items) {
this.items = items;
}
@Override
public boolean matches(Object item) {
List list = (List) (item);
int l = -1;
for (String s : items) {
int i = list.indexOf(s);
if (i == -1 || i < l) {
return false;
}
l = i;
}
return true;
}
@Override
public void describeTo(Description description) {
// not implemented
}
}
@Test
public void test1() {
List<String> list = Arrays.asList("foo", "bar", "boo");
Assert.assertThat(list, new ListMatcher("foo", "boo"));
Assert.assertThat(list, new ListMatcher("boo", "foo"));
}
答案 3 :(得分:1)
接受的答案对我不起作用。它仍然失败,说
Expected: iterable containing ["foo", "boo"] but: Not matched: "bar"
所以我写了自己的IsIterableContainingInRelativeOrder和submitted it as a patch。
答案 4 :(得分:1)
我在http://www.baeldung.com/hamcrest-collections-arrays
找到了解决方案查找具有严格顺序示例的部分。
List<String> collection = Lists.newArrayList("ab", "cd", "ef");
assertThat(collection, contains("ab", "cd", "ef"));
基本上你需要使用包含匹配器(org.hamcrest.Matchers.contains
)
答案 5 :(得分:0)
您可以组合is
和equalTo
的匹配器库。 assert语句看起来更长,但错误消息更好。由于contains
首先是失败的,因此它在找到第一个不匹配项时就中断了,并且在列表的后面找不到失败。其中is
和equalTo
会打印整个列表,从中可以看到所有不匹配项。
使用contains
List<String> list = Arrays.asList("foo", "bar", "boo");
assertThat(list, contains("foo", "boo", "bar"));
给出以下错误消息:
Expected: iterable containing ["foo", "boo", "bar"]
but: item 1: was "bar"
使用is and equalTo
List<String> list = Arrays.asList("foo", "bar", "boo");
assertThat(list, is(equalTo(Lists.newArrayList("foo", "boo", "bar"))));
给出以下错误消息:
Expected: is <[foo, boo, bar]>
but: was <[foo, bar, boo]>
第二种方法不会告诉您索引不匹配的位置,但是对我来说,这仍然更好,因为您可以只查看一次失败消息来修复测试。而在方法一中,您将首先修复索引1,运行测试,检测索引2的不匹配并进行最终修复。