JUnit测试执行executeBatch()时抛出空指针异常排查
JUnit测试数据库批量插入触发空指针异常排查
问题背景
执行Java数据库层逻辑的JUnit单元测试时,代码行int[] counts = stmt.executeBatch();触发NullPointerException,已知数据库连接Connection、PreparedStatement的基础初始化逻辑已在测试类继承的父类中实现。
关联代码
待测试的插入方法
public int insertPerson(int num, String word, List<Integer> lists) { int count = -1; try(Connection conn = mgr.getConnection(connName); PreparedStatement stmt = conn.prepareStatement(Queries.INSERT_PERSON);) { try { conn.setAutoCommit(false); for (Integer lis: lists) { stmt.setInt(1, num); stmt.setString(2, word); stmt.setInt(3, lis); stmt.addBatch(); } int[] counts = stmt.executeBatch(); count = counts.length; conn.commit(); } catch (SQLException e) { // 省略异常处理逻辑 . . . } return count; }
对应单元测试用例
@Test void testInsertPerson() throws SQLException { int num = FakeDataGenerator.number(4); String word = FakeDataGenerator.randomString(5); List<Integer> lists = new ArrayList<>(); lists.add(number(1)); lists.add(number(1)); assertNotEquals(dao.insertPerson(num, word, lists), -1); }
排查方向
- 校验
Queries.INSERT_PERSON常量是否正确赋值:如果该常量值为null,部分JDBC驱动实现不会抛出异常,而是直接返回null类型的PreparedStatement实例,后续调用executeBatch()时必然触发空指针。 - 检查代码括号闭合逻辑:当前贴出的代码中外层try-with-resources块、内层try-catch块的闭合括号缺失,若实际代码存在作用域错误,可能导致
stmt对象在执行批处理前被意外回收或置空。 - 确认测试环境数据源配置:校验
connName对应的数据源配置是否在测试环境生效,mgr实例是否完成初始化。如果mgr.getConnection()返回的连接是代理空对象,创建PreparedStatement时可能静默返回null而非抛出SQL异常。 - 验证JDBC驱动兼容性:部分老旧版本JDBC驱动对批处理支持存在缺陷,执行
addBatch()过程中如果出现内部错误,可能不会正常抛出SQLException,反而将语句对象内部状态置空,触发后续执行时的空指针。 - 排查异常处理块逻辑:检查省略的
catch块代码,确认不存在手动将stmt置空、提前关闭语句/连接的逻辑,避免批处理执行前资源被意外释放。
内容的提问来源于stack exchange,提问作者A. T
相关产品推荐
相关产品推荐

