我无法验证模拟映射中是否存在对象,也无法验证该对象上是否调用了 register() 。 以下是测试中抛出的错误
Assert.assertNotNull(locationDataMonitor); //Throws assertionError
Mockito.verify(locationDataMonitor, Mockito.times(1)).register()); //org.mockito.exceptions.misusing.NullInsteadOfMockException:
实现
public class DataAcquisitionService {
private Map<String, IDataMonitor> dataMonitors;
public DataAcquisitionService (...) {
this.dataMonitors = new ConcurrentHashMap<>();
}
public void doSomething(String id) {
IDataMonitor dataMonitor = null;
if (this.dataMonitors.containsKey(locationId)) {
dataMonitor = this.dataMonitors.get(locationId);
dataMonitor.register();
}
}
}
测试
@RunWith(PowerMockRunner.class)
public class DataAcquisitionServiceTest {
@Mock
private Map<String, IDataMonitor> dataMonitors;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
locationDataMonitors = Mockito.mock(ConcurrentHashMap.class);
this.target = new DataAcquisitionService(..);
}
@Test
public void test_doSomething() {
String id = "id1";
this.target.doSomething(id);
IDataMonitor locationDataMonitor = this.dataMonitors.get(id)
Assert.assertNotNull(locationDataMonitor);
Mockito.verify(locationDataMonitor, Mockito.times(1)).register();
}
}
最佳答案
您只模拟需要控制的对象。
您永远不应该模拟简单的集合实例。您只需传递集合对象,这些对象携带使您的测试代码达到预期路径所需的内容。在您的情况下,您可以简单地将一个空映射传递给该类。调用被测试的方法后,您检查该 map 是否包含所需的内容。
要验证 map 的内容,您只需查询 map 的内容即可。例如,通过将 assertThat 断言与 hamcrest is 匹配器一起使用。
但准确地说:您不想编写需要了解此类实现细节的测试。您应该测试方法的公共(public)契约,而不是暴露您正在使用映射来保存值的事实。
最后:看来您不明白模拟对象实际上是什么。它们是模拟,似乎是某个类的实例。但他们绝对不了解真正的类(Class)。模拟映射不存储键和值。您唯一可以做的就是分别指定验证该模拟对象预计会发生哪些方法调用。
关于java - 当Map被mock时如何从Map中获取元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49217021/