Hamcrest для сопоставления Map со значением массива String - PullRequest
0 голосов
/ 18 октября 2018

Есть ли элегантный способ утверждать все записи карты, где значения на карте являются строковыми массивами?

Кажется, что 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 голосов
/ 20 октября 2018

Я не смог найти существующее решение для этого варианта использования. Вот пользовательский маркер, который я придумал. Обратите внимание, что я не проверил его полностью для всех возможных типов

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