简体   繁体   English

Hamcrest测试地图包含来自另一个地图的所有条目

[英]Hamcrest test that a map contains all entries from another map

I want to check that a map contains a certain set of entries. 我想检查地图是否包含某组条目。 It is allowed to contain other entries that are not in expectedMap . 允许包含不在expectedMap其他条目。 I currently have the following assertion: 我目前有以下断言:

assertThat(expectedMap.entrySet(), everyItem(isIn(actualMap.entrySet())));

Although this does work, the failure message that it prints is confusing because the expected and received arguments have been reversed from normal usage. 虽然这确实有效,但它打印的失败消息令人困惑,因为预期和接收的参数已从正常使用中反转。 Is there a better way to write it? 有没有更好的方法来写它?

hasItems does what you want, but in a non-obvious way. hasItems做你想要的,但是以一种非显而易见的方式。 You have to jump through some hoops as Hamcrest has relatively limited support for matching Iterable s. 你必须跳过一些箍,因为Hamcrest对匹配Iterable的支持相对有限。 (Without going into detail, this is due to the vagaries of how Java generics work- I'll post some more links with detail later). (没有详细说明,这是由于Java泛型如何工作的变幻莫测 - 我将在稍后发布一些更详细的链接)。

(I'm assuming you're using generics, eg Map<String, String> as opposed to simply Map ). (我假设你正在使用泛型,例如Map<String, String>而不是简单的Map )。

In the meantime you have a couple of options... 在此期间,您有几个选择......

If you are happy with test code that raises warnings / using @SuppressWarnings("unchecked") in your test: 如果您对在测试中使用@SuppressWarnings("unchecked")引发警告的测试代码感到满意:

assertThat(actualMap.entrySet(), (Matcher)hasItems(expectedMap.entrySet().toArray()));

Explanation: there is no overload of hasItems that takes a Set or Iterable , but it will take an array. 说明: hasItems没有带有SetIterable重载,但是它需要一个数组。 Set.toArray() returns Object[] , which won't match assertThat against your actualMap.entrySet() - but if you erase the declared type of the Matcher, it will happily proceed. Set.toArray()返回Object[] ,它与assertThat不匹配你的actualMap.entrySet() - 但如果你删除了Matcher的声明类型,它将很乐意继续。

If you want an assertion that compiles without warnings, it gets uglier - you need to copy the Set into some kind of Iterable<Object> (you can't cast) in order to match on the Objects : 如果你想要一个在没有警告的情况下编译的断言,它会变得更加丑陋 - 你需要将Set复制到某种Iterable<Object> (你不能强制转换)以便在Objects上匹配:

assertThat(new HashSet<Object>(actualMap.entrySet()), hasItems(expectedMap.entrySet().toArray()));

But to be perfectly honest, for clarity you are almost certainly best off asserting each entry individually: 但是说实话,为了清楚起见,你几乎肯定最好单独断言每个条目:

for (Entry<String, String> entry : expectedMap.entrySet()) {
    assertThat(actualMap, hasEntry(entry.getKey(), entry.getValue())); 
}

...or you could write your own Matcher - there are plenty of resources on how to do this online and on SO. ...或者你可以编写自己的匹配器 - 有很多关于如何在线和在线执行此操作的资源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM