Spring Boot中JdbcTemplate.batchUpdate的Mockito测试用例编写及异常问题求助
Spring Boot中JdbcTemplate.batchUpdate的Mockito测试用例编写及异常问题求助
嘿,我瞅了下你的问题,主要是几个小坑导致的:mock的JdbcTemplate没注入到AuditDao里(这是空指针的核心原因)、参数匹配器写法可以优化,还有mock的Audit对象没设置getter返回值的潜在问题。我帮你梳理下怎么修正:
问题根源拆解
- 空指针的核心原因:你测试用例里的
auditDao实例根本没拿到mock的JdbcTemplate!也就是说调用auditDao.batchInsert时,里面的jdbcTemplate还是null,直接调方法可不就空指针了嘛。 - 被掩盖的匹配器异常:你看到的
InvalidUseOfMatchersException是被空指针压制的异常,虽然你用了匹配器,但如果mock实例没注入,这个异常根本没机会触发主逻辑,先被空指针打断了。另外你的匹配器写法可以更简洁,不用硬写泛型。 - 潜在的Audit对象问题:你mock了Audit但没给它的
getId()、getSourceType()这些getter设返回值,当ParameterizedPreparedStatementSetter里调用这些方法时,mock对象默认返回null,这次测试可能没炸,但后续扩展逻辑肯定出问题。
修正后的完整测试用例
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.ParameterizedPreparedStatementSetter; import java.util.ArrayList; import java.util.List; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) // 启用Mockito的扩展支持 public class AuditDaoTest { @Mock // 生成JdbcTemplate的mock实例 private JdbcTemplate jdbcTemplate; @InjectMocks // 自动把mock的jdbcTemplate注入到auditDao里 private AuditDao auditDao; @Test public void testBatchInsert() { // 用真实Audit对象比mock省心多了,直接设属性就行 List<Audit> auditList = new ArrayList<>(); Audit audit = new Audit(); audit.setId(1L); audit.setSourceType("TEST_SOURCE"); audit.setJson("{\"data\":\"test\"}"); auditList.add(audit); // 简化匹配器写法,不用纠结泛型 when(jdbcTemplate.batchUpdate(anyString(), anyList(), anyInt(), any(ParameterizedPreparedStatementSetter.class))) .thenReturn(new int[][]{{1}}); // 用assertArrayEquals比较数组,assertEquals对多维数组是比引用,不准 int[][] result = auditDao.batchInsert(auditList); assertArrayEquals(new int[][]{{1}}, result); } }
关键修正点说明
- 正确注入Mock:用
@Mock生成JdbcTemplate的mock,再用@InjectMocks自动注入到auditDao,这样auditDao里的jdbcTemplate就不是null了,空指针直接解决。 - 用真实Audit对象:比起mock Audit然后一个个设getter返回值,直接new真实对象设属性太香了,既符合真实业务场景,又省代码。
- 优化匹配器:用
anyString()、anyList()、anyInt()这些针对性的匹配器代替泛型写法,代码更清爽,也避免泛型匹配的小坑。 - 数组比较用assertArrayEquals:
assertEquals对多维数组是比较对象引用,而assertArrayEquals会逐元素对比,结果更准确。
如果你非要用mock的Audit对象
那记得给每个getter方法设置返回值,不然调用时会返回null:
Audit audit = Mockito.mock(Audit.class); when(audit.getId()).thenReturn(1L); when(audit.getSourceType()).thenReturn("TEST_SOURCE"); when(audit.getJson()).thenReturn("{\"data\":\"test\"}");
这样ParameterizedPreparedStatementSetter里调用这些方法时就有值啦~
备注:内容来源于stack exchange,提问作者Rahul
相关产品推荐
相关产品推荐

