真正有效的做法是:在轻量级数据库(如 h2)上启动真实的 sqlsession,配合 mybatis 测试支持机制完成集成式单元测试;推荐 h2 内存库 + mybatis-spring-boot-starter,或手动构建 sqlsessionfactory 并调用真实 mapper 代理。

直接对 MyBatis 的 Mapper 接口做单元测试,不能只靠纯内存 Mock(比如用 Mockito 模拟接口方法),因为 Mapper 的核心逻辑(SQL 执行、参数绑定、结果映射)依赖 MyBatis 运行时和数据库。所以**真正有效的做法是:在轻量级数据库(如 H2)上启动一个真实的 SqlSession,配合 MyBatis 测试支持机制完成集成式单元测试**。
用 H2 内存数据库 + MyBatis-Spring-Boot-Starter 测试
这是最常用、最贴近真实场景的方式,适合 Spring Boot 项目:
- 添加 test 范围的 H2 依赖和 testcontainers(可选,更接近生产)
- 写一个
@TestConfiguration或复用主配置,把SqlSessionFactory和DataSource(指向 H2)注入测试上下文 - 用
@MapperScan扫描你的 Mapper 接口,或用@MapperTest(MyBatis-Spring-Boot-Starter 3.0+ 支持) - 在测试类上加
@SpringBootTest或@DataJpaTest(需适配,推荐@ImportTestConfiguration更精准)
手动构建 SqlSession(无 Spring 环境)
如果你的项目没用 Spring,或者想彻底解耦框架做最小验证:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 创建 H2
DataSource,执行建表 SQL(可用Schema.sql) - 用
org.apache.ibatis.session.SqlSessionFactoryBuilder构建SqlSessionFactory,传入 H2 数据源和 Mapper XML / 注解配置 - 通过
sqlSessionFactory.openSession()获取SqlSession - 调用
session.getMapper(YourMapper.class)得到真实代理对象,再执行方法 - 记得
session.commit()(如果用了 INSERT/UPDATE)和session.close()
用 @Select 等注解 + @TestDatabase 配合 H2(推荐轻量组合)
避免 XML 维护成本,全部用注解定义 SQL:
- Mapper 接口方法用
@Select("SELECT * FROM user WHERE id = #{id}")等 - H2 建表语句保持与实体一致(注意类型映射,如 H2 的
VARCHAR对应 JavaString) - 测试前插入测试数据(可用
@Sql注解或 JUnit 5 的@BeforeEach中用 JDBC 插入) - 断言返回对象是否非空、字段值是否匹配,不建议只断言 size
避坑提醒
几个高频出错点:
- 别忘了设置 H2 的 DATABASE_TO_LOWER=true,否则表名大小写可能不匹配(尤其 Windows 下)
- Mapper XML 文件要放在
src/test/resources并确保被 classpath 加载(Maven 要配置<testresources></testresources>) - 使用
@MapperScan时,包路径必须包含测试中的 Mapper 接口位置 - 事务默认不自动回滚 —— 加
@Transactional+@Rollback可保证每个测试干净隔离
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










