Hamcrest Matchers.contains matcher不工作(?)

时间:2014-03-28 18:10:36

标签: java junit hamcrest

我正在尝试测试集合是否有一个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;

我做错了吗?

1 个答案:

答案 0 :(得分:17)

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

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

陈述

  

为Iterables创建一个只在单次传递时匹配的匹配器   在检查过的Iterable上产生至少一个匹配的项目   指定的itemMatcher。在匹配时,遍历了   一旦找到匹配的项目,检查Iterable就会停止。

Matchers.contains,正如您所说,

  

为Iterables创建一个匹配器,在单次传递时匹配   被检查的Iterable产生一个满足条件的项目   指定的匹配器。对于肯定匹配,检查的可迭代必须   只生产一件物品。

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