2014-09-03 6 views
10

hasProperty может быть использован с hasItem для проверки значения данного свойства, например:Hamcrest согласовань для проверки возвращаемого значения методы в коллекции

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

Это хорошо, когда имя является свойством, а именно: есть это метод, называемый getName().

Есть ли соответствующий элемент, который будет проверять метод, который не является свойством? т.е.: , в этом случае он проверяет возвращаемое значение метода name(), а не getName(), для предметов в коллекции.

+0

Итак, вы хотите вызвать метод name() для всех элементов коллекции? –

ответ

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

Преимущества вы получите с этим более настраиваемой согласованью является то, что он полностью многоразовым и компонуем с другими matchers как все это делает данные экстракции затем отбрасывает все, что вы хотите. Вы также получите соответствующую диагностику, например. в приведенном выше примере вы будете, если вы измените утверждение на значение, которое вы не получили:

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().

Смежные вопросы