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