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

如何为DAO层catch块编写JUnit测试用例以提升代码覆盖率?

问题:Spring Boot DAO层JUnit测试无法覆盖catch块

我正在为Spring Boot项目编写JUnit测试用例,目标是达到90%的代码覆盖率。现在想覆盖DAO层方法里的catch块,但写的测试用例没生效,覆盖不了。

DAO层代码

public class GeneratorRepository {

    @Value("${existingQuery}")
    private String existingQuery;

    @Autowired
    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Autowired
    private BeanPropertyRowMapper<Generator> generatorRowMapper;


    public Generator findExisting(Request request) {
        Generator ut = new Generator();
        try {
            SqlParameterSource namedParameters = new MapSqlParameterSource()
                    .addValue("no", request.getId(), Types.VARCHAR)
                    .addValue("trSu", request.getSu(), Types.VARCHAR)
                    .addValue("sta", request.getSta(), Types.VARCHAR);
            ut = namedParameterJdbcTemplate.queryForObject(existingQuery, namedParameters, generatorRowMapper);
        } catch (EmptyResultDataAccessException e) {
            ut = null;
        } catch (Exception e) {
            throw e;
        }
        return ut;
    }

}

现有测试用例(未覆盖catch块)

@Test
public void findExistingException() {
    Request request = new Request("12365", "QW", "qw");
    
    when(namedParameterJdbcTemplate.queryForObject(ArgumentMatchers.<String>any(), any(SqlParameterSource.class), eq(generatorRowMapper))).thenReturn(null);
    
    when(generatorRepo.findExisting(request)).thenThrow(new EmptyResultDataAccessException(1));
    EmptyResultDataAccessException exception = assertThrows(EmptyResultDataAccessException.class, () -> generatorRepo.findExisting(request));
}

解决方案

原测试用例的问题

  1. 错误地直接mock了generatorRepo.findExisting(request)的行为,相当于跳过方法内部逻辑直接抛异常,根本触发不了catch块
  2. namedParameterJdbcTemplate.queryForObject查询无结果时会抛出EmptyResultDataAccessException,而非返回null,原mock的返回值不符合实际逻辑

修正后的测试用例

测试EmptyResultDataAccessException catch块

@Test
public void findExisting_WhenEmptyResult_ThenReturnNull() {
    Request request = new Request("12365", "QW", "qw");
    
    // 让queryForObject抛出EmptyResultDataAccessException,触发第一个catch块
    when(namedParameterJdbcTemplate.queryForObject(
            ArgumentMatchers.<String>any(),
            any(SqlParameterSource.class),
            eq(generatorRowMapper)
    )).thenThrow(new EmptyResultDataAccessException(1));
    
    // 调用方法,验证返回值为null(catch块中设置的结果)
    Generator result = generatorRepo.findExisting(request);
    assertNull(result);
}

测试通用Exception catch块

@Test
public void findExisting_WhenGenericException_ThenThrowException() {
    Request request = new Request("12365", "QW", "qw");
    RuntimeException testException = new RuntimeException("test error");
    
    // 让queryForObject抛出通用Exception,触发第二个catch块
    when(namedParameterJdbcTemplate.queryForObject(
            ArgumentMatchers.<String>any(),
            any(SqlParameterSource.class),
            eq(generatorRowMapper)
    )).thenThrow(testException);
    
    // 验证方法会重新抛出该异常
    RuntimeException thrownException = assertThrows(RuntimeException.class, () -> generatorRepo.findExisting(request));
    assertEquals(testException, thrownException);
}

内容的提问来源于stack exchange,提问作者Rahul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 00:05:20