我需要根据一个特定的键值从一个模拟对象发送一个特定的值.
具体类:
map.put("xpath","PRICE"); search(map);
从测试用例:
IoUrXMLDocument mock = mock(IoUrXMLDocument.class); when(mock.search(.....need help here).thenReturn("$100.00");
解决方法
我发现这试图解决一个类似的问题,创建一个带有Map参数的Mockito存根.我不想为有关的地图编写一个自定义匹配器,然后我找到一个更优雅的解决方案:在mockito的argThat中使用
hamcrest-library中的附加匹配器:
when(mock.search(argThat(hasEntry("xpath","PRICE"))).thenReturn("$100.00");
如果您需要检查多个条目,那么您可以使用其他hamcrest的好东西:
when(mock.search(argThat(allOf(hasEntry("xpath","PRICE"),hasEntry("otherKey","otherValue")))).thenReturn("$100.00");
这开始长时间不平凡的地图,所以我最终提取方法来收集入门匹配器并将它们粘贴到我们的TestUtils中:
public static <K,V> Matcher<Map<K,V>> matchesEntriesIn(Map<K,V> map) { return allOf(buildMatcherArray(map)); } public static <K,V>> matchesAnyEntryIn(Map<K,V> map) { return anyOf(buildMatcherArray(map)); } @SuppressWarnings("unchecked") private static <K,V> Matcher<Map<? extends K,? extends V>>[] buildMatcherArray(Map<K,V> map) { List<Matcher<Map<? extends K,? extends V>>> entries = new ArrayList<Matcher<Map<? extends K,? extends V>>>(); for (K key : map.keySet()) { entries.add(hasEntry(key,map.get(key))); } return entries.toArray(new Matcher[entries.size()]); }
所以我留下来:
when(mock.search(argThat(matchesEntriesIn(map))).thenReturn("$100.00"); when(mock.search(argThat(matchesAnyEntryIn(map))).thenReturn("$100.00");
有一些与泛型相关的丑陋,我正在抑制一个警告,但至少它是干燥的,隐藏在TestUtil中.
最后一个注意事项,请注意embedded hamcrest issues in JUnit 4.10.使用Maven,我建议先导入hamcrest-library,然后再导入JUnit 4.11(并且从JUnit中排除hamcrest-core只是为了很好的测量):
<dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-library</artifactId> <version>1.3</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> <exclusions> <exclusion> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-core</artifactId> </exclusion> </exclusions> </dependency>