Apache POI行迭代问题



我得到空指针,而测试下面的代码

public static List<String> getColumnList(Row row) {
List<String> columnList = new ArrayList<>();
**for(Cell cell : row){**
if(StringUtils.isEmpty(cell.getStringCellValue())){
break;
}else{
columnList.add(cell.getStringCellValue());
}
}
return columnList;
}

测试代码如下

Workbook mockWorkbook = mock(Workbook.class);
Sheet mockSheet = mock(Sheet.class);
Row mockRow = mock(Row.class);
Cell mockCell1 = mock(Cell.class);
Cell mockCell2 = mock(Cell.class);
Cell mockCell3 = mock(Cell.class);
Cell mockCell4 = mock(Cell.class);
when(mockWorkbook.createSheet("m_digi_svce_func_asset_cat")).thenReturn(mockSheet);
when(mockWorkbook.getNumberOfSheets()).thenReturn(1);
when(mockWorkbook.getSheetAt(0)).thenReturn(mockSheet);
when(mockWorkbook.isSheetHidden(0)).thenReturn(false);
when(mockSheet.getSheetName()).thenReturn("m_digi_svce_func_asset_cat");
when(mockWorkbook.getSheet("m_digi_svce_func_asset_cat")).thenReturn(mockSheet);
when(mockSheet.createRow(0)).thenReturn(mockRow);
when(mockRow.createCell(0)).thenReturn(mockCell1);
when(mockRow.createCell(1)).thenReturn(mockCell2);
when(mockRow.createCell(2)).thenReturn(mockCell3);
when(mockRow.createCell(3)).thenReturn(mockCell4);
when(mockRow.getCell(0)).thenReturn(mockCell1);
when(mockCell1.getStringCellValue()).thenReturn("test1");
when(mockRow.getCell(1)).thenReturn(mockCell2);
when(mockCell2.getStringCellValue()).thenReturn("test2");
when(mockRow.getCell(2)).thenReturn(mockCell3);
when(mockCell3.getStringCellValue()).thenReturn("test3");
when(mockRow.getCell(3)).thenReturn(mockCell4);
when(mockCell4.getStringCellValue()).thenReturn("test4");
assertNotNull(mockRow.getCell(0).getStringCellValue());
assertNotNull(getColumnList(mockRow));

代码在getColumnList中的Row的每个循环中失败,说Row是空的。

任何帮助/指针将不胜感激。

根据Lesiak的建议,我添加了以下代码,现在运行正常。

Iterator<Cell> cellIterator = mock(Iterator.class);
when(mockRow.iterator()).thenReturn(cellIterator);
when(cellIterator.hasNext()).thenReturn(true).thenReturn(true).thenReturn(true).thenReturn(true).thenReturn(false);
when(cellIterator.next()).thenReturn(mockCell1).thenReturn(mockCell2).thenReturn(mockCell3).thenReturn(mockCell4);
when(mockRow.getCell(0)).thenReturn(mockCell1);
when(mockCell1.getStringCellValue()).thenReturn("test1");
when(mockRow.getCell(1)).thenReturn(mockCell2);
when(mockCell2.getStringCellValue()).thenReturn("test2");
when(mockRow.getCell(2)).thenReturn(mockCell3);
when(mockCell3.getStringCellValue()).thenReturn("test3");
when(mockRow.getCell(3)).thenReturn(mockCell4);
when(mockCell4.getStringCellValue()).thenReturn("test4");
assertNotNull(mockRow.getCell(0).getStringCellValue());

foreach循环调用mockRow.iterator()方法,该方法没有存根。

请熟悉Java '每个'循环的工作吗?

除此之外:即使在测试这样一个简单的方法时,看起来也有很多交互。对于更复杂的方法,模拟设置将变得更加复杂。这表明嘲笑并不是最佳解决方案。考虑在内存中使用真实的实现来创建工作簿,而不是模拟。

见https://www.codejava.net/coding/how-to-write-excel-files-in-java-using-apache-poi

我的意思是:

public static Workbook buildTestWorkbook()  {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("Java Books");
Object[][] bookData = {
{"Head First Java", "Kathy Serria", 79},
{"Effective Java", "Joshua Bloch", 36},
{"Clean Code", "Robert martin", 42},
{"Thinking in Java", "Bruce Eckel", 35},
};
int rowCount = 0;
for (Object[] aBook : bookData) {
Row row = sheet.createRow(++rowCount);
int columnCount = 0;
for (Object field : aBook) {
Cell cell = row.createCell(++columnCount);
if (field instanceof String) {
cell.setCellValue((String) field);
} else if (field instanceof Integer) {
cell.setCellValue((Integer) field);
}
}
}
return workbook;
}