有没有一种优雅的方法来断言 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/