我正在尝试测试集合是否有一个toString()方法返回特定String的项。我尝试使用优秀的Hamcrest匹配类,通过将contains与Matchers.hasToString
组合,但不知何故,它Matchers.contains
无法匹配项目,即使它存在于集合中。
以下是一个例子:
class Item {
private String name;
public Item(String name){
this.name = name;
}
public String toString(){
return name;
}
}
// here's a sample collection, with the desired item added in the end
Collection<Item> items = new LinkedList<Item>(){{
add(new Item("a"));
add(new Item("b"));
add(new Item("c"));
}};
Assert.assertThat(items, Matchers.contains(Matchers.hasToString("c")));
以上断言不成功。这是消息:
java.lang.AssertionError:
Expected: iterable containing [with toString() "c"]
but: item 0: toString() was "a"
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.junit.Assert.assertThat(Assert.java:865)
at org.junit.Assert.assertThat(Assert.java:832)
看起来Matchers.contains匹配器尝试迭代列表,但Matchers.hasToString匹配器在第一个项目中失败并使迭代的其余部分无效。 Matchers.contains的Hamcrest javadoc说:
&#34;为Iterables创建匹配器,当对检查的Iterable进行单次传递产生满足指定匹配器的单个项时匹配。对于肯定匹配,检查的可迭代必须仅产生一个项目&#34;
我做错了吗?
答案 0 :(得分:17)
我认为您正在寻找Matchers.hasItem(..)
Assert.assertThat(items, Matchers.hasItem(Matchers.hasToString("c")));
陈述
为Iterables创建一个只在单次传递时匹配的匹配器 在检查过的
Iterable
上产生至少一个匹配的项目 指定的itemMatcher
。在匹配时,遍历了 一旦找到匹配的项目,检查Iterable
就会停止。
Matchers.contains
,正如您所说,
为Iterables创建一个匹配器,在单次传递时匹配 被检查的
Iterable
产生一个满足条件的项目 指定的匹配器。对于肯定匹配,检查的可迭代必须 只生产一件物品。
在我看来,在Iterable
中应该只有一个元素。