2014-09-03 24 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()方法的類或接口。