Hamcrest将Map与String数组值匹配

时间:2018-10-18 20:39:39

标签: java arrays hamcrest

是否有一种优雅的方法来断言Map中所有值都是String数组的map的所有条目?

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

此断言失败。

1 个答案:

答案 0 :(得分:0)

我找不到针对该用例的现有解决方案,这是我想出的自定义行进器。 请注意,我并未针对所有可能的类型进行全面测试

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

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

失败方案

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