How do I match an empty collection using TestNG and hasItem
from Hamcrest? This is what I get as a result of one test.
java.lang.AssertionError:
Expected: a collection containing email = null phone = null
got: <[]>
Here is my matcher class:
private static class MyPersonMatcher extends TypeSafeMatcher<Person> {
private final String email;
private final String phone;
public ContactAgentUsageMatcher() {
}
public ContactAgentUsageMatcher(String email, String phone, Integer listingId) {
this.email = email;
this.phone = phone;
}
@Override
public void describeTo(Description description) {
description.appendText("email = ");
description.appendValue(this.email);
description.appendText(" phone = ");
description.appendValue(this.phone);
}
@Override
public boolean matchesSafely(ContactAgentUsage contactAgentUsage) {
if ((this.email == null) && (this.phone == null)) {
return true;
}
else {
return ObjectUtils.equals(this.email, contactAgentUsage.getEmail())
&& ObjectUtils.equals(this.phone, contactAgentUsage.getPhone());
}
}
}
The test that fails is
assertThat(argument.getAllValues(), hasItem(expectedMatcher));
where expectedMatcher
is provided by data provider. I am not sure what to pass to match this "empty collection" as a result. I am passing default constructor but I know this doesn't work because it creates collection with null
members.
This is part of my data provider:
{ new ContactAgentUsageMatcher()}
Your custom matcher will match any existing Person
when the configured email
and name
are both set to null
. However, the collection doesn't contain any Person
s to match against. Hamcrest's hasItem(matcher)
fails the test in this case and is the wrong matcher to use for empty collections.
Here are two workarounds:
Change the data provider and tests to take the full matcher including hasItem
. For the above case you would pass emptyIterable
. The downside is that you'll need to tell the Java compiler which generic type it should use which will clutter the tests.
Create a second test to handle the data sets that produce an empty collection.