2014-03-28 38 views
5

我想测试一个集合是否有toString()方法返回一个特定字符串的项目。我尝试使用优秀的Hamcrest匹配类来做到这一点,通过组合包含Matchers.hasToString,但不知何故,其Matchers.contains不能匹配项目,即使它存在于集合中。Hamcrest Matchers.contains matcher not working(?)

下面是一个例子:

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说:

“为Iterables创建一个匹配器,匹配时检查Iterable上的单个遍将产生满足指定匹配器的单个项目。对于正匹配,检查的迭代只能产生一个item“

我做错了什么?

回答

14

我认为你正在寻找Matchers.hasItem(..)

Assert.assertThat(items, Matchers.hasItem(Matchers.hasToString("c"))); 

其中规定

Creates a matcher for Iterables that only matches when a single pass over the examined Iterable yields at least one item that is matched by the specified itemMatcher . Whilst matching, the traversal of the examined Iterable will stop as soon as a matching item is found.

Matchers.contains,如你所说,

Creates a matcher for Iterables that matches when a single pass over the examined Iterable yields a single item that satisfies the specified matcher. For a positive match, the examined iterable must only yield one item.

在我看来,像在说应该只有Iterable中的一个元素。

+0

索蒂里奥斯,我试过hasItem,却得到了一个编译器错误:在类的方法assertThat(T,匹配器)断言是不适用的参数(?收藏,匹配器<可迭代<超级对象>>) – JulioAragao

+0

@ JulioAragao我按照原样复制了示例代码,并用'hasItem'替换了'contains'。 –

+0

是的,我想你是对的@Sotirios。我改变了由包含匹配器迭代的列表中的顺序,以便首先出现“c”,但即使如此也不会通过。我将调查为什么我有这个编译问题,但我认为你已经明确了它。谢谢! – JulioAragao