Хамкрест равных коллекций

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

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

Ответ 1

Я не могу сравнивать Arrays.asList и Map.values ​​с Hamcrest равно.

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

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

Ответ 2

Кастинг в коллекцию может работать, но он делает некоторые предположения о базовых реализациях Collection (например, 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));
    }
}

Ответ 3

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

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

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

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