比较忽略给定字段的地图
Compare maps ignoring given fields
我觉得我在这里遗漏了一些明显的东西,但文档让我失望了。我试图在忽略 assertJ 中的一组字段的同时比较两个映射。我希望看到这个断言通过:
private static final String[] IGNORED_FIELDS = { "ignored", "another" };
private static final Map<String, Object> TEST_PAYLOAD = ImmutableMap.of("test", "payload", "example", "value", "ignored", "field");
private static final Map<String, Object> COMPARISON_PAYLOAD = ImmutableMap.of("test", "payload", "example", "value", "another", "ignored field");
// assert fails
assertThat(TEST_PAYLOAD).isEqualToIgnoringGivenFields(COMPARISON_PAYLOAD, IGNORED_FIELDS);
然而,实际发生的比较是地图对象,并在大小、modCount、阈值等方面失败。此外,它实际上并没有忽略在比较表、键和值。我也试过使用
assertThat(TEST_PAYLOAD).usingRecursiveComparison().ignoringGivenFields(IGNORED_FIELDS).isEqualTo(COMPARISON_PAYLOAD);
但这失败了,因为它试图比较被忽略的字段。这里有一个优雅的解决方案,还是我必须手动遍历键?
testPayload
实际上包含这些键值对:
"test" -> "payload",
"example" -> "value",
"ignored" -> "field"
比较负载有这些键值对:
"test" -> "payload",
"example" -> "value",
"another" -> "ignored field"
也就是说,您需要将.ignoringGivenFields(IGNORED_FIELDS)
应用于两个有效负载才能成功。在您的第一次尝试中,您从比较中删除了 "another"
,但 "ignored"
仍保留在测试负载中;第二次尝试时反之亦然。
ignoringGivenFields()
将不起作用,因为它是一个 ObjectAssert
,而不是 MapAssert
方法,并且如您所指出的那样对对象的属性而不是地图的键进行操作。
就是说,我相信没有您可以使用的内置 AssertJ 方法,但是您可以编写自己的过滤器方法并在进行相等性测试之前应用它:
private static <V> Map<String, V> filterIgnoredKeys(Map<String, V> map) {
return Maps.filterKeys(map, key -> !IGNORED_FIELDS.contains(key));
}
// later
assertThat(filterIgnoredKeys(TEST_PAYLOAD))
.isEqualTo(filterIgnoredKeys(COMPARISON_PAYLOAD))
如果你想让方案更优雅,可以尝试your own custom assertion。
我觉得我在这里遗漏了一些明显的东西,但文档让我失望了。我试图在忽略 assertJ 中的一组字段的同时比较两个映射。我希望看到这个断言通过:
private static final String[] IGNORED_FIELDS = { "ignored", "another" };
private static final Map<String, Object> TEST_PAYLOAD = ImmutableMap.of("test", "payload", "example", "value", "ignored", "field");
private static final Map<String, Object> COMPARISON_PAYLOAD = ImmutableMap.of("test", "payload", "example", "value", "another", "ignored field");
// assert fails
assertThat(TEST_PAYLOAD).isEqualToIgnoringGivenFields(COMPARISON_PAYLOAD, IGNORED_FIELDS);
然而,实际发生的比较是地图对象,并在大小、modCount、阈值等方面失败。此外,它实际上并没有忽略在比较表、键和值。我也试过使用
assertThat(TEST_PAYLOAD).usingRecursiveComparison().ignoringGivenFields(IGNORED_FIELDS).isEqualTo(COMPARISON_PAYLOAD);
但这失败了,因为它试图比较被忽略的字段。这里有一个优雅的解决方案,还是我必须手动遍历键?
testPayload
实际上包含这些键值对:
"test" -> "payload",
"example" -> "value",
"ignored" -> "field"
比较负载有这些键值对:
"test" -> "payload",
"example" -> "value",
"another" -> "ignored field"
也就是说,您需要将.ignoringGivenFields(IGNORED_FIELDS)
应用于两个有效负载才能成功。在您的第一次尝试中,您从比较中删除了 "another"
,但 "ignored"
仍保留在测试负载中;第二次尝试时反之亦然。
ignoringGivenFields()
将不起作用,因为它是一个 ObjectAssert
,而不是 MapAssert
方法,并且如您所指出的那样对对象的属性而不是地图的键进行操作。
就是说,我相信没有您可以使用的内置 AssertJ 方法,但是您可以编写自己的过滤器方法并在进行相等性测试之前应用它:
private static <V> Map<String, V> filterIgnoredKeys(Map<String, V> map) {
return Maps.filterKeys(map, key -> !IGNORED_FIELDS.contains(key));
}
// later
assertThat(filterIgnoredKeys(TEST_PAYLOAD))
.isEqualTo(filterIgnoredKeys(COMPARISON_PAYLOAD))
如果你想让方案更优雅,可以尝试your own custom assertion。