You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 02:27:01