2014-09-03 4 views
10

hasProperty mit hasItem verwendet werden, um den Wert einer bestimmten Eigenschaft zu überprüfen, zB:hamcrest Matcher für in Sammelrückgabewert Methode Überprüfung

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

Das ist in Ordnung, wenn der Name eine Eigenschaft ist, das heißt: es ist eine Methode namens getName().

Gibt es einen Matcher, der eine Methode prüft, die keine Eigenschaft ist? dh: In diesem Fall wird der Rückgabewert der Methode name() anstelle von getName() für Artikel in der Sammlung überprüft.

+0

so, möchten Sie den Namen() -Methode auf alle Artikel einer Kollektion nennen? –

Antwort

12

Sie können einen anderen Hamcrest-Built-In dafür verwenden, einen FeatureMatcher. Diese sind so konzipiert, dass sie mit anderen Matchern kombiniert werden können, nachdem sie Ihre Eingabe in etwas anderes verwandelt haben. Also in Ihrem Fall, dass Sie so etwas tun würde:

@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(); 
     } 
    }; 
} 

Der Nutzen Sie mit diesem über einen benutzerdefinierten Matcher zu bekommen ist, dass es mit anderen Matcher wie alle tut es vollständig wiederverwendbar und zusammensetzbare ist, ist die Datenextraktion dann sich auf jeden anderen Matcher verlagern, den Sie wollen. Sie werden auch eine geeignete Diagnose erhalten, z.B. Im obigen Beispiel werden Sie, wenn Sie die Assertion auf einen Wert ändern, nicht die gegenwärtige erhalten Sie:

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

können Sie ein selbst schreiben:

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); 
    } 
} 

Wo MyClass eine Klasse oder Schnittstelle, die die name() Methode definiert.

Verwandte Themen