MyBatis-Plus 单元测试及 H2 数据库应用
在进行 DAO 层单元测试时,如果使用 @SpringBootTest
启动整个项目进行集成测试,会导致启动速度非常慢,影响测试效率。本文整理了 MyBatis-Plus 单元测试的方法,并介绍如何使用 H2 数据库进行测试,以提高测试效率。
使用 H2 数据库进行单元测试
H2 数据库是一个内存数据库,适用于单元测试场景。可以使用 @MybatisPlusTest
注解来快速配置 MyBatis-Plus 的测试环境。
基本测试配置
less
@MybatisPlusTest
@Sql(scripts = {"classpath:db/schema.sql", "classpath:db/data.sql"})
@MapperScan({"mapper包"})
//@ContextConfiguration(classes={*Service.class}) // 如果测试 Service,可以仅加载该 Service 类
public class Test {
// 单元测试代码
}
注解解析
@MapperScan
:指定 MyBatis Mapper 接口所在的包,使其在编译后生成对应的实现类。@Sql
:测试前执行 SQL 脚本进行数据库初始化。@ContextConfiguration
:如果需要加载ApplicationContext
的配置文件或配置类,可以使用该注解。例如,加载yml
配置文件时可添加initializers = {ConfigFileApplicationContextInitializer.class}
。
使用 Java 配置 H2 数据源
除了使用默认 H2 数据源外,我们也可以手动配置 H2 数据库。
typescript
public class DataSourceConfig {
@Bean
public DruidDataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1");
return dataSource;
}
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}
该配置类未添加 @Configuration
,以避免影响到其他单元测试的数据源。在单元测试类中可以用 @Import
引入该配置类:
less
@ExtendWith(SpringExtension.class)
@Import({DataSourceConfig.class})
public class JunitTest {
@Autowired
private UserMapper userMapper;
@Test
public void testInsertUser() {
User user = new User();
user.setName("Test User");
user.setAge(25);
userMapper.insert(user);
User insertedUser = userMapper.selectById(user.getId());
assertNotNull(insertedUser);
assertEquals("Test User", insertedUser.getName());
}
}
如果需要在测试时实时观察 H2 数据库的数据变化,可以使用服务器模式,修改 URL 为:
bash
jdbc:h2:tcp://localhost:9092/~/testdb;DB_CLOSE_DELAY=-1
启动 H2 Server 进行调试
如果希望在本地连接 H2 数据库,可以启动 H2 服务器。
csharp
public class H2ServerTest {
private static Server h2Server;
public static void startH2Server() throws Exception {
// 启动 H2 服务器
h2Server = Server.createTcpServer("-tcp", "-tcpAllowOthers", "-tcpPort", "9092").start();
System.out.println("H2 server started on port 9092");
}
public static void stopH2Server() {
// 停止 H2 服务器
if (h2Server != null) {
h2Server.stop();
System.out.println("H2 server stopped");
}
}
}
使用 MySQL 作为测试数据库
如果需要使用应用的 MySQL 数据库进行单元测试,可以添加以下注解:
less
@Transactional // 确保测试后回滚数据,避免污染数据库
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) // 使用实际数据库,而非默认的 H2
@MybatisPlusTest
@Sql(scripts = {"classpath:db/schema.sql", "classpath:db/data.sql"})
@MapperScan({"mapper包"})
//@ContextConfiguration(classes={*Service.class})
public class Test {
// 单元测试代码
}
注解解析
@Transactional
:确保测试后回滚数据库,防止污染数据。@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
:避免@MybatisPlusTest
默认使用 H2 数据库,而改用 MySQL。
总结
使用 H2 数据库进行 MyBatis-Plus 单元测试可以显著提升测试效率,并避免影响实际数据库。对于更接近生产环境的测试,可以结合 @Transactional
和 @AutoConfigureTestDatabase
直接使用 MySQL 数据库,同时确保数据回滚,避免污染环境。