简体   繁体   English

用于检查集合中方法的返回值的Hamcrest匹配器

[英]Hamcrest matcher for checking return value of method in collection

hasProperty can be used with hasItem to check for the value of a given property, eg: hasProperty可以与hasItem一起使用来检查给定属性的值,例如:

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

This is fine when name is a property, ie: there is a method called getName() . 当name是属性时,这很好,即:有一个名为getName()的方法。

Is there a matcher that will check a method that isn't a property? 是否有匹配器会检查不属于某个属性的方法? ie: in this case, it will check the return value of the method name() rather than getName() , for items in the collection. ie:在这种情况下,它将检查方法name()的返回值,而不是getName() ,用于集合中的项目。

You can use another Hamcrest built-in for this, a FeatureMatcher . 你可以使用另一个内置的Hamcrest,一个FeatureMatcher These are designed to be combined with other matchers after they transform your input into something else. 这些设计旨在将其输入转换为其他内容后与其他匹配器结合使用。 So in your case you would do something like this: 所以在你的情况下,你会做这样的事情:

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

The benefit you'll get with this over a custom matcher is that it's fully reusable and composable with other matchers as all it does is the data-extraction then defers to whatever other matcher you want. 通过自定义匹配器获得的好处是,它可以完全重用并可与其他匹配器组合,因为它所做的就是数据提取然后推送到您想要的任何其他匹配器。 You're also going to get appropriate diagnostics, eg in the above example you will if you change the assert to a value that's not present you will receive: 您还将获得适当的诊断,例如在上面的示例中,如果您将断言更改为您将收到的不存在的值,您将会:

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

You can write one yourself: 你可以自己写一个:

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

Where MyClass is a class or interface which defines the name() method. 其中MyClass是定义name()方法的类或接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM