Java 使用迭代器 forEach() 时如何正确测试 POI Row 和 Cell 的模拟实例
Java how to test correctly mocked instances of POI Row and Cell when use iterator forEach()
鉴于此代码:
protected Sheet getSheet(String pathName, int sheetNumber) throws IOException {
File file = new File(pathName);
Workbook workbook = WorkbookFactory.create(file);
return workbook.getSheetAt(sheetNumber);
}
public List<String> getRowAsString(String pathName, int rowNumber) throws IOException {
Sheet sheet = getSheet(pathName, 0);
Row row = sheet.getRow(rowNumber);
List<String> cellsString = new ArrayList<>();
for (int i = 0; i < row.getLastCellNum(); i ++) {
cellsString.add(row.getCell(i).getStringCellValue());
}
return cellsString;
}
我可以用这个来测试它:
@Before
public void init() throws IOException {
when(workbookMock.getSheetAt(anyInt())).thenReturn(sheetMock);
PowerMockito.mockStatic(WorkbookFactory.class);
when(WorkbookFactory.create((File) any())).thenReturn(workbookMock);
}
@Test
public void should_return_wanted_row_as_string() throws IOException {
Row rowMock = mock(Row.class);
Cell cellMOck1 = mock(Cell.class);
when(cellMOck1.getStringCellValue()).thenReturn("Valor1");
Cell cellMOck2 = mock(Cell.class);
when(cellMOck2.getStringCellValue()).thenReturn("Valor2");
when(rowMock.getCell(0)).thenReturn(cellMOck1);
when(rowMock.getCell(1)).thenReturn(cellMOck2);
when(sheetMock.getRow(anyInt())).thenReturn(rowMock);
when(rowMock.getLastCellNum()).thenReturn((short) 2);
List<String> expected = List.of("Valor1", "Valor2");
List<String> result = sut.getRowAsString("/", 0);
assertEquals(expected, result);
}
但是,如果我想在 getRowAsString() 方法中使用 forEach() 而不是 for 循环,如下所示:
public List<String> getRowAsString(String pathName, int rowNumber) throws IOException {
Sheet sheet = getSheet(pathName, 0);
Row row = sheet.getRow(rowNumber);
List<String> cellsString = new ArrayList<>();
row.forEach(cell -> {
cellsString.add(cell.getStringCellValue());
});
return cellsString;
}
测试无效,因为使用 stream.forEach() 时代码没有调用方法 getCell(index)。
我应该如何测试方法才能使用 forEach() 而不是传统的 for 循环?
是的,我可以创建一个真实的工作簿实例,例如,使用 XSSFWorkbook class。
我尝试做这样的事情是错误的:
Workbook workbook = new XSSFWorkbook();
Sheet sheet = new XSSFSheet();
workbook.setSheet(sheet);
XSSFWorkbook 没有问题,但 XSSFSheet 具有受保护的访问权限,显然,我无法创建它的实例。
正确的方法是:
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow();
Cell cell = row.createCell();
...
我不知道使用表格的方式,我试图通过 classic 方式注入。
鉴于此代码:
protected Sheet getSheet(String pathName, int sheetNumber) throws IOException {
File file = new File(pathName);
Workbook workbook = WorkbookFactory.create(file);
return workbook.getSheetAt(sheetNumber);
}
public List<String> getRowAsString(String pathName, int rowNumber) throws IOException {
Sheet sheet = getSheet(pathName, 0);
Row row = sheet.getRow(rowNumber);
List<String> cellsString = new ArrayList<>();
for (int i = 0; i < row.getLastCellNum(); i ++) {
cellsString.add(row.getCell(i).getStringCellValue());
}
return cellsString;
}
我可以用这个来测试它:
@Before
public void init() throws IOException {
when(workbookMock.getSheetAt(anyInt())).thenReturn(sheetMock);
PowerMockito.mockStatic(WorkbookFactory.class);
when(WorkbookFactory.create((File) any())).thenReturn(workbookMock);
}
@Test
public void should_return_wanted_row_as_string() throws IOException {
Row rowMock = mock(Row.class);
Cell cellMOck1 = mock(Cell.class);
when(cellMOck1.getStringCellValue()).thenReturn("Valor1");
Cell cellMOck2 = mock(Cell.class);
when(cellMOck2.getStringCellValue()).thenReturn("Valor2");
when(rowMock.getCell(0)).thenReturn(cellMOck1);
when(rowMock.getCell(1)).thenReturn(cellMOck2);
when(sheetMock.getRow(anyInt())).thenReturn(rowMock);
when(rowMock.getLastCellNum()).thenReturn((short) 2);
List<String> expected = List.of("Valor1", "Valor2");
List<String> result = sut.getRowAsString("/", 0);
assertEquals(expected, result);
}
但是,如果我想在 getRowAsString() 方法中使用 forEach() 而不是 for 循环,如下所示:
public List<String> getRowAsString(String pathName, int rowNumber) throws IOException {
Sheet sheet = getSheet(pathName, 0);
Row row = sheet.getRow(rowNumber);
List<String> cellsString = new ArrayList<>();
row.forEach(cell -> {
cellsString.add(cell.getStringCellValue());
});
return cellsString;
}
测试无效,因为使用 stream.forEach() 时代码没有调用方法 getCell(index)。
我应该如何测试方法才能使用 forEach() 而不是传统的 for 循环?
是的,我可以创建一个真实的工作簿实例,例如,使用 XSSFWorkbook class。
我尝试做这样的事情是错误的:
Workbook workbook = new XSSFWorkbook();
Sheet sheet = new XSSFSheet();
workbook.setSheet(sheet);
XSSFWorkbook 没有问题,但 XSSFSheet 具有受保护的访问权限,显然,我无法创建它的实例。
正确的方法是:
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow();
Cell cell = row.createCell();
...
我不知道使用表格的方式,我试图通过 classic 方式注入。