Question

Is there a matcher in Hamcrest to compare collections for equality? There is contains and containsInAnyOrder but I need equals not bound to concrete collection type. E.g. I cannot compare Arrays.asList and Map.values with Hamcrest equals.

Thanks in advance!

Was it helpful?

Solution

I cannot compare Arrays.asList and Map.values with Hamcrest equals.

This is because of hamcrest's over-zealous type signatures. You can do this equality comparison, but you need to cast the List object to Collection before it'll compile.

I often have to do casting with Hamcrest, which feels wrong, but it's the only way to get it to compile sometimes.

OTHER TIPS

Casting to a Collection may work, but it makes some assumptions about the underlying Collection implementations (e.g., order?). A more general approach would be to write your own matcher.

Here's a nearly complete matcher implementation that does what you want (you'll need to fill in the imports and describeTo method). Note that this implementation requires all elements of two collections to be equal, but not necessarily in the same order.

public class IsCollectionOf<T> extends TypeSafeMatcher<Collection<T>> {
    private final Collection<T> expected;
    public IsCollectionOf(Collection<T> expected) {
        this.expected = expected;
    }
    public boolean matchesSafely(Collection<T> given) {
        List<T> tmp = new ArrayList<T>(expected);
        for (T t : given) {
            if (!tmp.remove(t)) {
                return false;
            }
        return tmp.isEmpty();
    }
    // describeTo here
    public static <T> Matcher<Collection<T>> ofItems(T... items) {
        return new IsCollectionOf<T>(Arrays.asList(items));
    }
}

If you have trouble with the equals method of the collections implementation, you might also first copy the collections:

assertThat( new ArrayList<Whatever>(actual), equalTo( new ArrayList<Whatever>(expected) );

Also the following might work:

assertThat(actual, both(everyItem(isIn(expected))).and(containsInAnyOrder(expected)));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top