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 方式注入。