11

Hamcrest 中是否有匹配器来比较集合是否相等?有containscontainsInAnyOrder但我不需要equals绑定到具体的集合类型。例如,我无法将 Arrays.asList 和 Map.values 与 Hamcrest 进行比较equals

提前致谢!

4

3 回答 3

7

我无法将 Arrays.asList 和 Map.values 与 Hamcrest equals 进行比较。

这是因为 hamcrest 过分热心的类型签名。您可以进行这种相等比较,但您需要在编译之前将List对象转换为。Collection

我经常不得不用 Hamcrest 进行铸造,这感觉不对,但有时这是让它编译的唯一方法。

于 2009-12-25T11:32:40.573 回答
4

强制转换为 Collection 可能有效,但它对底层的 Collection 实现做了一些假设(例如,订单?)。更通用的方法是编写自己的匹配器。

这是一个几乎完整的匹配器实现,可以满足您的需求(您需要填写导入和 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));
    }
}
于 2010-01-08T13:41:05.307 回答
1

如果你对集合实现的 equals 方法有问题,你也可以先复制集合:

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

以下也可能有效:

assertThat(actual, both(everyItem(isIn(expected))).and(containsInAnyOrder(expected)));
于 2012-08-27T15:54:13.730 回答