With Hamcrest we can easily test that exists at least one item in a list with a specific property, e.g.
List<Pojo> myList = ....
MatcherAssert.assertThat(myList, Matchers.hasItem(Matchers.<Pojo>hasProperty("fieldName", Matchers.equalTo("A funny string")))));
where the class Pojo
is something like:
public class Pojo{
private String fieldName;
}
That's nice, but how can I check that there is exactly one object in the list with the specificed properties?
Class StringContains. Tests if the argument is a string that contains a substring. Creates a matcher that matches if the examined String contains the specified String anywhere.
assertEquals() is the method of Assert class in JUnit, assertThat() belongs to Matchers class of Hamcrest. Both methods assert the same thing; however, hamcrest matcher is more human-readable. As you see, it is like an English sentence “Assert that actual is equal to the expected value”.
jUnit testing using hamcrest matcher - how to test the size of a collection.
Hamcrest vs TestNG TestNG is a testing framework, and as noted above, Hamcrest is a matcher framework. Both frameworks allow us to make assertions; it is here where Hamcrest does a better job than TestNG. TestNG is a testing framework, and as noted above, Hamcrest is a matcher framework.
You might have to write your own matcher for this. (I prefer the fest assertions and Mockito, but used to use Hamcrest...)
For example...
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.core.IsCollectionContaining;
public final class CustomMatchers {
public static <T> Matcher<Iterable<? super T>> exactlyNItems(final int n, Matcher<? super T> elementMatcher) {
return new IsCollectionContaining<T>(elementMatcher) {
@Override
protected boolean matchesSafely(Iterable<? super T> collection, Description mismatchDescription) {
int count = 0;
boolean isPastFirst = false;
for (Object item : collection) {
if (elementMatcher.matches(item)) {
count++;
}
if (isPastFirst) {
mismatchDescription.appendText(", ");
}
elementMatcher.describeMismatch(item, mismatchDescription);
isPastFirst = true;
}
if (count != n) {
mismatchDescription.appendText(". Expected exactly " + n + " but got " + count);
}
return count == n;
}
};
}
}
You can now do...
List<TestClass> list = Arrays.asList(new TestClass("Hello"), new TestClass("World"), new TestClass("Hello"));
assertThat(list, CustomMatchers.exactlyNItems(2, hasProperty("s", equalTo("Hello"))));
Example fail output when the list is...
List<TestClass> list = Arrays.asList(new TestClass("Hello"), new TestClass("World"));
...will be...
Exception in thread "main" java.lang.AssertionError:
Expected: a collection containing hasProperty("s", "Hello")
but: , property 's' was "World". Expected exactly 2 but got 1
(You might want to customise this a bit)
By the way, "TestClass" is...
public static class TestClass {
String s;
public TestClass(String s) {
this.s = s;
}
public String getS() {
return s;
}
}
Matchers.hasItems
specifically checks to see if the items you provide exist in the collection, what you're looking for is Matchers.contains
which ensures that the 2 collections are essentially the same - or in your case, equivalent according to the provided
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With