Given this code:
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:
@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:
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:
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:
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.