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

Spring Boot中JdbcTemplate.batchUpdate的Mockito测试用例编写及异常问题求助

Spring Boot中JdbcTemplate.batchUpdate的Mockito测试用例编写及异常问题求助

嘿,我瞅了下你的问题,主要是几个小坑导致的:mock的JdbcTemplate没注入到AuditDao里(这是空指针的核心原因)、参数匹配器写法可以优化,还有mock的Audit对象没设置getter返回值的潜在问题。我帮你梳理下怎么修正:

问题根源拆解

  1. 空指针的核心原因:你测试用例里的auditDao实例根本没拿到mock的JdbcTemplate!也就是说调用auditDao.batchInsert时,里面的jdbcTemplate还是null,直接调方法可不就空指针了嘛。
  2. 被掩盖的匹配器异常:你看到的InvalidUseOfMatchersException是被空指针压制的异常,虽然你用了匹配器,但如果mock实例没注入,这个异常根本没机会触发主逻辑,先被空指针打断了。另外你的匹配器写法可以更简洁,不用硬写泛型。
  3. 潜在的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);
    }
}

关键修正点说明

  1. 正确注入Mock:用@Mock生成JdbcTemplate的mock,再用@InjectMocks自动注入到auditDao,这样auditDao里的jdbcTemplate就不是null了,空指针直接解决。
  2. 用真实Audit对象:比起mock Audit然后一个个设getter返回值,直接new真实对象设属性太香了,既符合真实业务场景,又省代码。
  3. 优化匹配器:用anyString()、anyList()、anyInt()这些针对性的匹配器代替泛型写法,代码更清爽,也避免泛型匹配的小坑。
  4. 数组比较用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 12:13:11