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

如何Mock与Service层存在同名方法的DAO层进行测试?

DAO层测试实现方案

核心测试逻辑区分

首先明确和Service层同名方法的测试边界,两者完全不冲突:

  • Service层同名方法测试:核心验证业务规则、参数校验、事务、跨组件调用逻辑,测试时通常Mock DAO层返回
  • DAO层方法测试:仅验证数据访问逻辑的正确性,不涉及任何业务流程,测试直接和数据库交互

测试环境配置

推荐使用Spring Boot自带的测试注解搭建轻量测试环境,避免加载不必要的Service层Bean:

  • 用@JdbcTest注解标注DAO测试类,该注解会自动配置测试用嵌入式数据源(默认H2)、NamedParameterJdbcTemplate,仅扫描@Repository相关Bean,完全隔离Service层逻辑
  • 也可使用Testcontainers启动和生产环境一致的数据库实例,保证测试结果和生产行为完全匹配

测试用例设计

针对你提供的findSomething方法,需要覆盖以下核心场景:

  • 正常匹配场景:提前向测试库插入2-3条符合查询条件的myTable数据,调用方法后校验返回Set的大小、每个MyForm属性和插入数据完全一致
  • 无匹配数据场景:仅插入不符合查询条件的数据,校验方法返回空集合而非Null
  • 参数绑定正确性场景:重点验证时区转换逻辑,传入带指定时区(如东8区)的ZonedDateTime参数,校验最终执行的SQL中绑定的时间参数为对应UTC时间,查询结果符合预期
  • 去重逻辑校验:插入两条完全相同、会被MyForm的equals/hashCode判定为重复的数据,校验返回Set的大小为1,验证HashSet去重逻辑正常
  • 字段映射校验:插入所有字段均有值的测试数据,校验MyRowMapper返回的MyForm所有属性和数据库存储值一致,不存在字段漏映射、类型转换错误问题

示例测试代码

// 仅加载Jdbc相关配置,不加载Service层Bean
@JdbcTest
@Import(DaoImpl.class)
class DaoImplTest {

    @Autowired
    private Dao dao;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Test
    void findSomething_ShouldReturnMatchingRecords() {
        // 准备测试数据
        ZonedDateTime inputTime = ZonedDateTime.of(2024, 5, 20, 12, 0, 0, 0, ZoneId.of("Asia/Shanghai"));
        jdbcTemplate.update("INSERT INTO myTable(title, name, mydatetime) VALUES (?, ?, ?)",
                "测试标题", "测试名称", inputTime.withZoneSameInstant(ZoneId.of("UTC")).toOffsetDateTime());

        // 调用DAO方法
        Set<MyForm> result = dao.findSomething("测试标题", "测试名称", inputTime);

        // 校验结果
        assertThat(result).hasSize(1);
        MyForm form = result.iterator().next();
        assertThat(form.getTitle()).isEqualTo("测试标题");
        assertThat(form.getName()).isEqualTo("测试名称");
        // 其他字段校验
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:15:03