如何在被模拟时从 Map 中获取元素



我无法验证模拟映射中是否存在对象,也无法验证是否在该对象上调用了 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();  
}
}

你只模拟需要控制的对象。

你永远不应该模拟简单的集合实例。您只需传递集合对象,这些对象携带使受测代码成为预期路径所需的内容。在您的情况下,您可以简单地将空映射传递给该类。调用所测试的方法后,检查该映射是否包含所需的内容。

要验证地图的内容,您只需查询地图的内容即可。例如,通过使用断言断言与腓头匹配器。

但确切地说:您不想编写需要了解此类实现细节的测试。您应该测试方法的公共合约,而不是公开使用映射来保存值的事实。

最后:您似乎不了解模拟对象实际上是关于什么的。它们是似乎是某个类的实例的模拟。但他们对真正的阶级一无所知。模拟映射不存储键和值。您唯一能做的是分别指定验证该模拟对象预期发生的方法调用。

看起来您希望在服务中的集合中保存IDataMonitor对象,并在某些情况下尝试对这些对象调用方法 (register())。

这里的方法是模拟一个IDataMonitor对象,将其放入集合中(可能通过在DataAcquisitionService上调用现有的公共方法),然后运行测试。

使用的内部集合应与测试无关。

我只能假设您有这样的方法,让您的IDataMonitor进入服务:

// within DataAcquisitionService
...
public void addMonitor(IDataMonitor monitor) {
this.dataMonitors.put(monitor.getId(), monitor);
}

然后你可以在测试中做这样的事情:

private IDataMonitor monitor;
@Before
public void setUp() {   
...  
this.monitor = Mockito.mock(IDataMonitor.class); 
Mockito.when(monitor.getId()).thenReturn("id1");
this.target = new DataAcquisitionService(..);
this.target.addMonitor(monitor); // now monitor is in the map
}
@Test
public void test_doSomething() { 
String id = "id1"; 
// as our monitor mock with "id1" is in the map, it is found and the register() method is called
this.target.doSomething(id);
// verify method call on the mocked monitor
Mockito.verify(this.monitor, Mockito.times(1)).register(); 
}

希望这有帮助!

相关内容

  • 没有找到相关文章

最新更新