我试图将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)并不起作用。有什么想法吗?
答案 0 :(得分:2)
如果仔细观察,nullValue(Class<T>)
只会创建一个IsNull<T>
匹配器。
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));
}