Java Hamcrest将映射与字符串数组值匹配

Java Hamcrest将映射与字符串数组值匹配,java,arrays,hamcrest,Java,Arrays,Hamcrest,如果映射中的值是字符串数组,是否有一种优雅的方法来断言映射的所有条目 Matchers.equals似乎根据数组的内容检查数组的相等性,而不是相等性: Map<String, String[]> x = new HashMap<>(); Map<String, String[]> y = new HashMap<>(); x.put("a", new String[] {"a", "b"}); y.put("a", new Str

如果映射中的值是字符串数组,是否有一种优雅的方法来断言映射的所有条目

Matchers.equals似乎根据数组的内容检查数组的相等性,而不是相等性:

  Map<String, String[]> x = new HashMap<>();
  Map<String, String[]> y = new HashMap<>();

  x.put("a", new String[] {"a", "b"});
  y.put("a", new String[] {"a", "b"});

  assertThat(y.entrySet(), Matchers.everyItem(Matchers.isIn(x.entrySet())));
Map x=newhashmap();
Map y=新的HashMap();
x、 put(“a”,新字符串[]{“a”,“b”});
y、 put(“a”,新字符串[]{“a”,“b”});
断言(y.entrySet(),Matchers.everyItem(Matchers.isIn(x.entrySet()));

此断言失败。

我找不到此用例的现有解决方案,这是我提出的自定义marcher请注意,我没有对所有可能的类型进行彻底测试

public static class MapEntryMatcher<K, V> extends TypeSafeDiagnosingMatcher<Map.Entry<K, V>> {

    private final Map<K,V> expectedMap;

    public MapEntryMatcher(Map<K, V> expectedMap) {
        this.expectedMap = expectedMap;
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("Map are Equivalent");
    }

    @Override
    protected boolean matchesSafely(Map.Entry<K, V> item, Description description) {
        if (expectedMap.get(item.getKey()) == null){
            description.appendText("key '" + item.getKey() + "' is not present");
            return false;
        } else {
            if (item.getValue().getClass().isArray()) {
                boolean b = Arrays.deepEquals((Object[]) expectedMap.get(item.getKey()), (Object[]) item.getValue());
                if (!b) description.appendText("array value is not equal for key: " + item.getKey());
                return b;
            } else {
                return expectedMap.get(item.getKey()).equals(item.getValue());
            }
        }
    }
}
公共静态类MapEntryMatcher扩展了TypeSafeDiagnosingMatcher{
私人最终地图预期地图;
公共映射匹配器(映射预期映射){
this.expectedMap=expectedMap;
}
@凌驾
公共无效说明(说明){
说明.附录文字(“地图等同”);
}
@凌驾
受保护的布尔匹配安全(Map.Entry项,说明){
if(expectedMap.get(item.getKey())==null){
description.appendText(“key'+item.getKey()+”不存在);
返回false;
}否则{
if(item.getValue().getClass().isArray()){
布尔b=Arrays.deepEquals((Object[])expectedMap.get(item.getKey()),(Object[])item.getValue());
如果(!b)description.appendText(“数组值对于键:“+item.getKey()”)不相等);
返回b;
}否则{
返回expectedMap.get(item.getKey()).equals(item.getValue());
}
}
}
}
OP中的测试场景

@Test
void test1()
{
    Map<String, String[]> x = new HashMap<>();
    Map<String, String[]> y = new HashMap<>();

    x.put("a", new String[] {"a", "b"});
    y.put("a", new String[] {"a", "b"});

    assertThat(y.entrySet(), Every.everyItem(new MapEntryMatcher<>(x)));
}
@测试
void test1()
{
Map x=新的HashMap();
Map y=新的HashMap();
x、 put(“a”,新字符串[]{“a”,“b”});
y、 put(“a”,新字符串[]{“a”,“b”});
断言(y.entrySet(),Every.everyItem(新的MapEntryMatcher(x));
}
失败情景

@Test
void test2()
{
    Map<String, String[]> x = new HashMap<>();
    Map<String, String[]> y = new HashMap<>();

    x.put("a", new String[] {"a", "b"});
    x.put("B", new String[]{"a"});

    y.put("a", new String[] {"a", "b", "D"});
    y.put("B", new String[]{"a"});

    assertThat(y.entrySet(), Every.everyItem(new MapEntryMatcher<>(x)));
}

@Test
void test3()
{
    Map<String, String[]> x = new HashMap<>();
    Map<String, String[]> y = new HashMap<>();

    x.put("a", new String[] {"a", "b"});
    x.put("B", new String[]{"a"});

    y.put("a", new String[] {"a", "b"});
    y.put("D", new String[]{"a"});

    assertThat(y.entrySet(), Every.everyItem(new MapEntryMatcher<>(x)));
}
@测试
void test2()
{
Map x=新的HashMap();
Map y=新的HashMap();
x、 put(“a”,新字符串[]{“a”,“b”});
x、 put(“B”,新字符串[]{“a”});
y、 put(“a”,新字符串[]{“a”,“b”,“D”});
y、 put(“B”,新字符串[]{“a”});
断言(y.entrySet(),Every.everyItem(新的MapEntryMatcher(x));
}
@试验
void test3()
{
Map x=新的HashMap();
Map y=新的HashMap();
x、 put(“a”,新字符串[]{“a”,“b”});
x、 put(“B”,新字符串[]{“a”});
y、 put(“a”,新字符串[]{“a”,“b”});
y、 put(“D”,新字符串[]{“a”});
断言(y.entrySet(),Every.everyItem(新的MapEntryMatcher(x));
}