使用 Mockito,如何匹配映射的键值对?
我需要根据特定的键值从模拟对象发送特定的值。
从具体类:
map.put("xpath", "PRICE");
search(map);
从测试用例:
IOurXMLDocument mock = mock(IOurXMLDocument.class);
when(mock.search(.....need help here).thenReturn("$100.00");
如何模拟此键值对的方法调用?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我发现这试图解决创建带有 Map 参数的 Mockito 存根的类似问题。我不想为有问题的地图编写自定义匹配器,然后我找到了一个更优雅的解决方案:使用 hamcrest-library 与mockito的argThat:
如果你需要检查多个条目,那么你可以使用其他hamcrest好东西:
这开始变得很长与不平凡的地图,所以我结束了提取方法来收集条目匹配器并将它们粘贴在我们的 TestUtils 中:
所以我留下了:
与泛型相关的一些丑陋,我抑制了一个警告,但至少它是 DRY 并隐藏在 TestUtil 中。
最后一点,请注意 JUnit 中的 嵌入式 hamcrest 问题4.10。使用 Maven,我建议首先导入 hamcrest-library,然后导入 JUnit 4.11(现在为 4.12),并从 JUnit 中排除 hamcrest-core 只是为了更好的措施:
编辑:2017 年 9 月 1 日 - 根据一些评论,我更新了我的答案以显示我的Mockito 依赖项、我在测试 util 中的导入以及截至今天以绿色运行的 junit:
I found this trying to solve a similar issue creating a Mockito stub with a Map parameter. I didn't want to write a custom matcher for the Map in question and then I found a more elegant solution: use the additional matchers in hamcrest-library with mockito's argThat:
If you need to check against multiple entries then you can use other hamcrest goodies:
This starts to get long with non-trivial maps, so I ended up extracting methods to collect the entry matchers and stuck them in our TestUtils:
So I'm left with:
There's some ugliness associated with the generics and I'm suppressing one warning, but at least it's DRY and hidden away in the TestUtil.
One last note, beware the embedded hamcrest issues in JUnit 4.10. With Maven, I recommend importing hamcrest-library first and then JUnit 4.11 (now 4.12) and exclude hamcrest-core from JUnit just for good measure:
Edit: Sept 1, 2017 - Per some of the comments, I updated my answer to show my Mockito dependency, my imports in the test util, and a junit that is running green as of today:
如果您只想“匹配”特定的 Map,您可以使用上面的一些答案,或扩展 Map 的自定义“匹配器”对象,或 ArgumentCaptor,如下所示:
另请参阅此处的更多答案: 使用mockito验证对象属性值
如果要捕获多个地图:
If you just want to "match" against a particular Map, you can use some of the answers above, or a custom "matcher" Object that extends Map<X, Y>, or an ArgumentCaptor, like this:
See also more answers here: Verify object attribute value with mockito
If you want to capture multiple maps:
对于像我这样遇到这个问题的人来说,实际上有一个基于 Lambda 的非常简单的解决方案:
解释:
argThat
需要一个ArgumentMatcher
,它是一个函数式接口,因此可以写为一个拉姆达。For anyone arriving to this question like myself, there's actually a very simple solution based on Lambdas:
Explanation:
argThat
expects anArgumentMatcher
which is a functional interface and thus can be written as a Lambda.这行不通吗?
Map
参数的行为方式应与其他参数相同。Doesn't this work?
The
Map
parameter should behave the same way as other parameters.似乎您需要的是一个
Answer
:但似乎更好的主意是不要使用原始
Map
作为搜索方法的参数 - 您可能可以将此地图转换为具有price
和productName
属性的 pojo。只是一个想法:)Seems like what you need is an
Answer
:But what seems like a better idea is to not use primitive
Map
as parameter to your search method - you could probably transform this map into a pojo withprice
andproductName
attributes. Just an idea :)