java - Hamcrest 将 Map 与 String 数组值匹配

标签 java arrays hamcrest

有没有一种优雅的方法来断言 Map 中的所有条目,其中 Map 中的值是 String 数组?

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

此断言失败。

最佳答案

我找不到这个用例的现有解决方案,这是我想出的自定义 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());
            }
        }
    }
}

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

关于java - Hamcrest 将 Map 与 String 数组值匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52882219/

相关文章:

java - getClass().getMethod ("name",未知)

java - 将 JCheckBox 的状态获取到 Java 中的另一个类?

C++初学者声明涉及结构数组的函数

java - 为排序的字符串列表创建测试用例

java - 断言集合中的每个字符串都包含子字符串的最佳方法?

java - 如何使用流获取数组列表的特定值

ios - 如何将查询中的数据保存在字符串数组中,Firebase iOS?

arrays - 如何在 ruby​​ 中对数组元素求和?

java - Hamcrest 的 lessThan 无法编译

java - 动态 jPanel 按钮 actionCommand