有没有办法创建一个静态方法,它将返回匹配集合或匹配null的Hamcrest匹配器?

时间:2014-01-14 15:55:11

标签: java hamcrest

我试图将Hamcrest匹配器引入我团队的一些代码中。为了避免匹配实例集合的复杂性,我想为我的每个匹配器编写一个帮助器方法,我希望匹配它的集合。所以本质上我包装了containsInAnyOrder。话虽这么说,如果有人将null作为预期和实际传递,我希望它匹配。但是我编写代码的方式,如果为预期的传入null,它将抛出NullPointerException。所以我想返回一个IsNull匹配器,如果null作为预期传入。这是我的示例代码:

/**
 * Matches all Foo objects in an order agnostic manner.
 * @param expected The collection of Foo objects to be matched.
 * @return A matcher that will match a collection of Foos
 */
@SuppressWarnings("unchecked")
public static Matcher<Iterable<? extends Foo>> matchesAllfoos(Collection<Foo> expected)
{
    if (expected == null)
    {
        // Doesn't work because Matcher<Iterable> is not a Matcher<Iterable<? extends Foo>>
        return nullValue(Iterable.class);
    }

    // The cast is here to provide a hint to Java as to which overloaded method to choose.
    // See http://stackoverflow.com/questions/18614621/conflicting-overloads-for-hamcrest-matcher
    return containsInAnyOrder((Collection)Collections2.transform(expected, FOO_TO_MATCHER));
}

那么我该如何完成我想做的事呢?使用nullValue()并不起作用,因为它希望我返回Matcher。转换nullValue(Iterable.class)并不起作用。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

如果仔细观察,nullValue(Class<T>)只会创建一个IsNull<T>匹配器。

所以,if you are calling

public static <T> Matcher<T> nullValue(Class<T> type) {
    return new IsNull<T>();
}

最后(因为你不能弄清楚潜在的null对象的运行时类,因为泛型会给你带来困难),你可以直接调用构造函数:

new IsNull<Iterable<? extends Foo>>();

所以解决方案就是使用它,而不使用nullValue()实用程序方法:

/**
 * Matches all Foo objects in an order agnostic manner.
 * @param expected The collection of Foo objects to be matched.
 * @return A matcher that will match a collection of Foos
 */
@SuppressWarnings("unchecked")
public static Matcher<Iterable<? extends Foo>> matchesAllfoos(Collection<Foo> expected)
{
    if (expected == null)
    {
        return new IsNull<Iterable<? extends Foo>>();
    }

    // The cast is here to provide a hint to Java as to which overloaded method to choose.
    // See http://stackoverflow.com/questions/18614621/conflicting-overloads-for-hamcrest-matcher
    return containsInAnyOrder((Collection)Collections2.transform(expected, FOO_TO_MATCHER));
}