Apache POI Row迭代单元测试出现空指针异常的问题求助
空指针异常问题排查与解决
异常根因
Java中对实现了Iterable接口的类使用for-each循环遍历,本质是自动调用类的iterator()方法获取迭代器完成遍历。你使用Mockito mock了Row对象,但没有为iterator()方法配置返回值,Mockito对未配置mock方法的引用类型返回值默认返回null,因此for-each循环执行时拿到空迭代器触发空指针异常。
你之前仅mock了getCell相关方法,但for-each遍历Row不会调用getCell,仅依赖迭代器实现,因此之前的mock配置不生效。
解决方案
按照如下配置补充Row迭代器的mock逻辑即可解决问题:
Iterator<Cell> cellIterator = mock(Iterator.class); // 配置Row的iterator方法返回mock的迭代器 when(mockRow.iterator()).thenReturn(cellIterator); // 配置迭代器hasNext返回序列:4个元素返回4次true,第5次返回false终止循环 when(cellIterator.hasNext()).thenReturn(true).thenReturn(true).thenReturn(true).thenReturn(true).thenReturn(false); // 配置迭代器next返回序列:依次返回4个mock的Cell对象 when(cellIterator.next()).thenReturn(mockCell1).thenReturn(mockCell2).thenReturn(mockCell3).thenReturn(mockCell4); // 原有getCell相关mock配置保持不变 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));
可选优化建议
- 可以在业务方法开头增加入参非空校验,避免外部传入空
Row时触发异常:public static List<String> getColumnList(Row row) { if (row == null) { return Collections.emptyList(); } List<String> columnList = new ArrayList<>(); // 原有逻辑不变 } - 如果不想额外mock迭代器,也可以把业务代码中的for-each循环改成普通for循环遍历,依赖
getCell方法实现,和你原有mock逻辑兼容:public static List<String> getColumnList(Row row) { List<String> columnList = new ArrayList<>(); int cellCount = row.getPhysicalNumberOfCells(); for (int i = 0; i < cellCount; i++) { Cell cell = row.getCell(i); if(StringUtils.isEmpty(cell.getStringCellValue())){ break; }else{ columnList.add(cell.getStringCellValue()); } } return columnList; }
内容的提问来源于stack exchange,提问作者sujikin
相关产品推荐
相关产品推荐

