使用 Hamcrest 映射相等

2022-08-31 17:31:23

我想使用hamcrest来断言两个映射是相等的,即它们具有相同的一组指向相同值的键。

我目前最好的猜测是:

assertThat( affA.entrySet(), hasItems( affB.entrySet() );

它给出:

类型中的方法不适用于参数 (assertThat(T, Matcher<T>)AssertSet<Map.Entry<Householdtypes,Double>>, Matcher<Iterable<Set<Map.Entry<Householdtypes,Double>>>>)

我还研究了 的变体,以及 hamcrest 软件包提供的其他一些变体。任何人都可以为我指出正确的方向吗?还是我必须编写自定义匹配器?containsAll


答案 1

我想出的最短方法是两种说法:

assertThat( affA.entrySet(), everyItem(isIn(affB.entrySet())));
assertThat( affB.entrySet(), everyItem(isIn(affA.entrySet())));

但你可能也可以做到:

assertThat(affA.entrySet(), equalTo(affB.entrySet()));

取决于地图的实现,并牺牲差异报告的清晰度:这只会告诉你存在差异,而上面的语句也会告诉你是哪一个。

更新:实际上有一个语句独立于集合类型工作:

assertThat(affA.entrySet(), both(everyItem(isIn(affB.entrySet()))).and(containsInAnyOrder(affB.entrySet())));

答案 2

有时就足够了。但有时你不知道测试中的代码返回的类型,所以你不知道是否会正确地将代码返回的未知类型的映射与你构造的映射进行比较。或者您不想将代码与此类测试绑定。Map.equals()Map.equals()

此外,单独构建地图以将结果与结果进行比较恕我直言,这并不是很优雅:

Map<MyKey, MyValue> actual = methodUnderTest();

Map<MyKey, MyValue> expected = new HashMap<MyKey, MyValue>();
expected.put(new MyKey(1), new MyValue(10));
expected.put(new MyKey(2), new MyValue(20));
expected.put(new MyKey(3), new MyValue(30));
assertThat(actual, equalTo(expected));

我更喜欢使用马切尔斯:

import static org.hamcrest.Matchers.hasEntry;

Map<MyKey, MyValue> actual = methodUnderTest();
assertThat(actual, allOf(
                      hasSize(3), // make sure there are no extra key/value pairs in map
                      hasEntry(new MyKey(1), new MyValue(10)),
                      hasEntry(new MyKey(2), new MyValue(20)),
                      hasEntry(new MyKey(3), new MyValue(30))
));

我必须定义自己:hasSize()

public static <K, V> Matcher<Map<K, V>> hasSize(final int size) {
    return new TypeSafeMatcher<Map<K, V>>() {
        @Override
        public boolean matchesSafely(Map<K, V> kvMap) {
            return kvMap.size() == size;
        }

        @Override
        public void describeTo(Description description) {
            description.appendText(" has ").appendValue(size).appendText(" key/value pairs");
        }
    };
}

还有另一种变体,它将匹配器作为参数,而不是键和值的精确值。如果您需要对每个键和值进行相等性测试以外的其他操作,这可能很有用。hasEntry()