Коллекции Hamcrest equal

есть ли сопоставитель в Hamcrest для сравнения коллекций для равенства? Есть contains и containsInAnyOrder но мне нужен equals не привязан к конкретному типу коллекции. Например. Я не могу сравнивать массивы.asList и карта.значения с Hamcrest equals.

спасибо заранее!

3 ответов


Я не могу сравнивать массивы.asList и Карта.значения с Hamcrest равны.

это из-за чрезмерно рьяных подписей типа hamcrest. Вы can сделайте это сравнение равенства, но вам нужно бросить List объект Collection перед компиляцией.

мне часто приходится делать кастинг с Hamcrest, что кажется неправильным, но это единственный способ заставить его иногда компилироваться.


приведение к коллекции может работать, но оно делает некоторые предположения о базовых реализациях коллекции (например, order?). Более общим подходом было бы написать свой собственный matcher.

вот почти полная реализация matcher, которая делает то, что вы хотите (вам нужно будет заполнить метод imports и describeTo). Обратите внимание, что эта реализация требует, чтобы все элементы двух коллекций были равны, но не обязательно в одном порядке.

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));
    }
}

Если у вас возникли проблемы с методом Equals реализации коллекций, вы также можете сначала скопировать коллекций:

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

также может работать следующее:

assertThat(actual, both(everyItem(isIn(expected))).and(containsInAnyOrder(expected)));