gpt4 book ai didi

java - 使用 Mockito,我如何匹配 map 的键值对?

转载 作者:搜寻专家 更新时间:2023-10-30 19:51:29 25 4
gpt4 key购买 nike

我需要根据特定键值从模拟对象发送特定值。

来自具体类:

map.put("xpath", "PRICE");
search(map);

来自测试用例:

IOurXMLDocument mock = mock(IOurXMLDocument.class);
when(mock.search(.....need help here).thenReturn("$100.00");

如何模拟这个键值对的方法调用?

最佳答案

我发现这试图解决创建带有 Map 参数的 Mockito stub 的类似问题。我不想为有问题的 Map 编写自定义匹配器,然后我找到了一个更优雅的解决方案:使用 hamcrest-library 中的附加匹配器。使用 mockito 的 argThat:

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 中:

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.hasEntry;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.hamcrest.Matcher;
---------------------------------
public static <K, V> Matcher<Map<K, V>> matchesEntriesIn(Map<K, V> map) {
return allOf(buildMatcherArray(map));
}

public static <K, V> Matcher<Map<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");

有一些与泛型相关的丑陋之处,我正在抑制一个警告,但至少它是 DRY 并且隐藏在 TestUtil 中。

最后一点,注意 embedded hamcrest issues in JUnit 4.10 .对于 Maven,我建议先导入 hamcrest-library,然后再导入 JUnit 4.11(现在是 4.12),并从 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.12</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>

编辑:2017 年 9 月 1 日 - 根据一些评论,我更新了我的答案以显示我的 Mockito 依赖项、我在测试实用程序中的导入以及截至今天运行绿色的 junit:

import static blah.tool.testutil.TestUtil.matchesAnyEntryIn;
import static blah.tool.testutil.TestUtil.matchesEntriesIn;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.HashMap;
import java.util.Map;

import org.junit.Test;

public class TestUtilTest {

@Test
public void test() {
Map<Integer, String> expected = new HashMap<Integer, String>();
expected.put(1, "One");
expected.put(3, "Three");

Map<Integer, String> actual = new HashMap<Integer, String>();
actual.put(1, "One");
actual.put(2, "Two");

assertThat(actual, matchesAnyEntryIn(expected));

expected.remove(3);
expected.put(2, "Two");
assertThat(actual, matchesEntriesIn(expected));
}

@Test
public void mockitoTest() {
SystemUnderTest sut = mock(SystemUnderTest.class);
Map<Integer, String> expected = new HashMap<Integer, String>();
expected.put(1, "One");
expected.put(3, "Three");

Map<Integer, String> actual = new HashMap<Integer, String>();
actual.put(1, "One");

when(sut.search(argThat(matchesAnyEntryIn(expected)))).thenReturn("Response");
assertThat(sut.search(actual), is("Response"));
}

protected class SystemUnderTest {
// We don't really care what this does
public String search(Map<Integer, String> map) {
if (map == null) return null;
return map.get(0);
}
}
}

关于java - 使用 Mockito,我如何匹配 map 的键值对?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2580369/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com