2014-09-03 56 views
10

hasProperty可以hasItem被用来检查给定属性的值,例如:Hamcrest匹配器在采集检查方法的返回值

Matcher hasName = Matchers<Person>hasProperty("name", is("Winkleburger")); 
assertThat(names, hasItem(hasName)); 

这是罚款时,名字是一个属性,即:有是一种名为getName()的方法。

是否有一个匹配器会检查一个不是属性的方法?即: 在这种情况下,它将检查方法name()的返回值,而不是getName(),该集合中的项目。

+0

因此,您想调用集合中所有项的name()方法吗? – 2014-09-03 14:24:10

回答

12

您可以使用另一个Hamcrest为此,一个FeatureMatcher。它们被设计成在将你的输入转换成别的东西后与其他匹配器相结合。所以你的情况,你会做这样的事情:

@Test 
public void test1() { 
    List<Person> names = new ArrayList<>(); 
    names.add(new Person("Bob")); 
    names.add(new Person("i")); 

    assertThat(names, hasItem(name(equalTo("Winkleburger")))); 
} 

private FeatureMatcher<Person, String> name(Matcher<String> matcher) { 
    return new FeatureMatcher<Person, String>(matcher, "name", "name") { 
     @Override 
     protected String featureValueOf(Person actual) { 
      return actual.name(); 
     } 
    }; 
} 

你会用这种过度的自定义匹配得到的好处是,它是完全可重复使用和可组合与其他的匹配因为它是所有的数据提取,然后按照你想要的任何其他匹配器。您还将获得适当的诊断,例如在上面的例子中,如果将断言改为不存在的值,您将收到:

java.lang.AssertionError: 
    Expected: a collection containing name "Batman" 
    but: name was "Bob", name was "Winkleburger" 
2

你可以自己写一个:

public class HasName extends TypeSafeMatcher<MyClass> { 
    private String expectedName; 

    private HasName(String expectedName) { 
     this.expectedName = expectedName; 
    } 

    @Override 
    public boolean matchesSafely(MyClass obj) { 
     return expectedName.equals(obj.name()); 
    } 

    @Factory 
    public static Matcher<MyClass> hasName(String expectedName) { 
     return new HasName(expectedName); 
    } 
} 

哪里MyClass是定义name()方法的类或接口。