hasProperty
可与hasItem
一起使用,以检查给定属性的值,例如:
Matcher hasName = Matchers<Person>hasProperty("name", is("Winkleburger"));
assertThat(names, hasItem(hasName));
当name是属性时,这很好,即:有一个名为getName()
的方法。
是否有匹配器会检查不属于某个属性的方法?即:
在这种情况下,对于集合中的项目,它将检查方法name()
而不是getName()
的返回值。
答案 0 :(得分:13)
你可以使用另一个内置的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"
答案 1 :(得分: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()
方法的类或接口。