使用hamcrest匹配Map包含不同类型的条目
Using hamcrest to match Map contains entries of different types
假设我有一张地图:
Map<String,Object> map1 = new HashMap<String,Object>();
map1.put("foo1","foo1");
map1.put("foo2", Arrays.asList("foo2","bar2"));
现在我想使用 Hamcrest 匹配器来验证地图的值。如果这是一个 Map< String,String > 我会做类似的事情:
assertThat(map1, hasEntry("foo1", "foo1"));
但是,当我尝试将其与 Map 一起使用时,我遇到了困难,因为 Map 中的条目可能是字符串或值列表。这适用于第一个条目:
assertThat(map1, hasEntry("foo1", (Object)"foo1"));
对于第二个条目,我不知道如何设置 Matchers。
编辑:
我也试过了,但它会产生编译器警告。
assertThat(
map1,
hasEntry(
"foo2",
contains(hasProperty("name", is("foo2")),
hasProperty("name", is("bar2")))));
"The method assertThat(T, Matcher) in the type Assert is not applicable for the arguments (Map, Matcher>>>)"
(以上是这里的解决方案:Hamcrest compare collections)
这样试试
你可以使用 ImmutableMap
assertThat( actualValue,
Matchers.<Map<String, Object>>equalTo( ImmutableMap.of(
"key1", "value",
"key2", "arrayrelated values"
) ) );
希望对你有用。
你不能用 Hamcrest 优雅地做到这一点 hasEntry
因为当你尝试在列表上使用匹配器时它会进行类型检查。
https://github.com/hamcrest/JavaHamcrest/issues/388
上有一个功能请求
我认为最简单的选择是做这样的事情:
@Test
public void test() {
Map<String, Object> map1 = new HashMap<>();
map1.put("foo1", "foo1");
map1.put("foo2", Arrays.asList("foo2", "bar2"));
assertThat(map1, hasEntry("foo1", "foo1"));
assertThat(map1, hasListEntry(is("foo2"), containsInAnyOrder("foo2", "bar2")));
}
@SuppressWarnings("unchecked")
public static org.hamcrest.Matcher<java.util.Map<String, Object>> hasListEntry(org.hamcrest.Matcher<String> keyMatcher, org.hamcrest.Matcher<java.lang.Iterable<?>> valueMatcher) {
Matcher mapMatcher = org.hamcrest.collection.IsMapContaining.<String, List<?>>hasEntry(keyMatcher, valueMatcher);
return mapMatcher;
}
hasListEntry
这里只是为了防止编译错误。它执行未经检查的分配,这就是您需要 @SuppressWarnings("unchecked") 的原因。例如,您可以将此静态方法放入您的通用测试工具中。
假设我有一张地图:
Map<String,Object> map1 = new HashMap<String,Object>();
map1.put("foo1","foo1");
map1.put("foo2", Arrays.asList("foo2","bar2"));
现在我想使用 Hamcrest 匹配器来验证地图的值。如果这是一个 Map< String,String > 我会做类似的事情:
assertThat(map1, hasEntry("foo1", "foo1"));
但是,当我尝试将其与 Map 一起使用时,我遇到了困难,因为 Map 中的条目可能是字符串或值列表。这适用于第一个条目:
assertThat(map1, hasEntry("foo1", (Object)"foo1"));
对于第二个条目,我不知道如何设置 Matchers。
编辑:
我也试过了,但它会产生编译器警告。
assertThat(
map1,
hasEntry(
"foo2",
contains(hasProperty("name", is("foo2")),
hasProperty("name", is("bar2")))));
"The method assertThat(T, Matcher) in the type Assert is not applicable for the arguments (Map, Matcher>>>)"
(以上是这里的解决方案:Hamcrest compare collections)
这样试试 你可以使用 ImmutableMap
assertThat( actualValue,
Matchers.<Map<String, Object>>equalTo( ImmutableMap.of(
"key1", "value",
"key2", "arrayrelated values"
) ) );
希望对你有用。
你不能用 Hamcrest 优雅地做到这一点 hasEntry
因为当你尝试在列表上使用匹配器时它会进行类型检查。
https://github.com/hamcrest/JavaHamcrest/issues/388
上有一个功能请求我认为最简单的选择是做这样的事情:
@Test
public void test() {
Map<String, Object> map1 = new HashMap<>();
map1.put("foo1", "foo1");
map1.put("foo2", Arrays.asList("foo2", "bar2"));
assertThat(map1, hasEntry("foo1", "foo1"));
assertThat(map1, hasListEntry(is("foo2"), containsInAnyOrder("foo2", "bar2")));
}
@SuppressWarnings("unchecked")
public static org.hamcrest.Matcher<java.util.Map<String, Object>> hasListEntry(org.hamcrest.Matcher<String> keyMatcher, org.hamcrest.Matcher<java.lang.Iterable<?>> valueMatcher) {
Matcher mapMatcher = org.hamcrest.collection.IsMapContaining.<String, List<?>>hasEntry(keyMatcher, valueMatcher);
return mapMatcher;
}
hasListEntry
这里只是为了防止编译错误。它执行未经检查的分配,这就是您需要 @SuppressWarnings("unchecked") 的原因。例如,您可以将此静态方法放入您的通用测试工具中。