Reputation: 4833
I'm trying to introduce Hamcrest matchers into some of the code for my team. In order to take the complexity out of matching a collection of instances, I want to write a helper method for each one of my matchers that I expect that it would be desirable to match collections of. So in essence I'm wrapping containsInAnyOrder. That being said, if someone passes in null as both the expected and actual, I want it to match. But the way I have my code written, it will throw a NullPointerException if null is passed in for the expected. So I want to return an IsNull matcher if null is passed in as the expected. Here's my sample code:
/**
* 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));
}
So how do I accomplish what I want to do? Using nullValue() doesn't work because then it expects me to return Matcher. Casting nullValue(Iterable.class) doesn't work. Any ideas?
Upvotes: 1
Views: 224
Reputation: 135752
If you look closely, nullValue(Class<T>)
simply creates a IsNull<T>
matcher.
So, if you are calling:
public static <T> Matcher<T> nullValue(Class<T> type) {
return new IsNull<T>();
}
In the end (as the generics are giving a hard time because you can't figure out the runtime class of a potentially null
object), you could just call the constructor directly:
new IsNull<Iterable<? extends Foo>>();
So a solution would be to just use it, without the nullValue()
utility method:
/**
* 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));
}
Upvotes: 2