Given this code:
JavaScript
x
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;
}
I can test it with this:
JavaScript
@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);
}
But, if I want to use forEach() instead of for loop in getRowAsString() method, like this:
JavaScript
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;
}
The test doesn’t work because when use stream.forEach() the code is not calling method getCell(index).
How should I test the method to be able to use forEach() instead of traditional for loop?
Advertisement
Answer
Yes, I can create a real instance of workbook using, for example, XSSFWorkbook class.
I was trying wrong to do something like this:
JavaScript
Workbook workbook = new XSSFWorkbook();
Sheet sheet = new XSSFSheet();
workbook.setSheet(sheet);
No problem with XSSFWorkbook, but XSSFSheet has protected access and, obviously, I can’t create an instance of it.
The correct way is:
JavaScript
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow();
Cell cell = row.createCell();
I did not know that way of working with sheets and I was trying to inject by the classic way.