Spring Boot如何创建测试专用数据库表并基于其配置EntityManager
Spring Boot 单测试表独立测试方案
实现步骤
1. 定义TestUser测试实体
仅保留测试需要用到的User表字段,字段名、类型和正式User实体完全一致即可:
@Entity @Table(name = "testUser") public class TestUser { @Id private long id; private String name; private String email; // 省略getter、setter、全参构造方法 }
2. 编写测试环境专用配置
在test资源目录下新建application-test.yml配置文件,配置内存H2数据库和表名映射规则:
spring: datasource: driver-class-name: org.h2.Driver url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1 username: sa password: jpa: hibernate: ddl-auto: create-drop # 测试启动自动建表,结束自动删表 properties: hibernate: # 配置测试环境表名映射策略 physical_naming_strategy: com.你的包名.TestTableNameMappingConfig show-sql: true # 可选,开启SQL打印方便调试
新增测试专用的表名映射配置类,仅测试环境生效,自动将业务代码中操作的user表路由到testUser表,无需修改原有业务代码:
import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; @Configuration @Profile("test") // 仅test profile激活 public class TestTableNameMappingConfig extends PhysicalNamingStrategyStandardImpl { @Override public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) { if ("user".equals(name.getText())) { // 把业务逻辑中的user表映射到测试用testUser表 return Identifier.toIdentifier("testUser"); } return super.toPhysicalTableName(name, context); } }
3. 编写测试用例
直接注入原有UserRepositoryImpl测试即可,测试启动会自动加载TestUser实体创建testUser表:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import javax.persistence.EntityManager; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; @SpringBootTest @ActiveProfiles("test") // 激活测试配置 public class UserRepositoryImplTest { @Autowired private UserRepositoryImpl userRepository; @Autowired private EntityManager em; @BeforeEach void initTestData() { // 提前插入模拟测试数据 TestUser user1 = new TestUser(1L, "张三", "zhangsan@test.com"); TestUser user2 = new TestUser(2L, "李四", "lisi@test.com"); em.persist(user1); em.persist(user2); em.flush(); } @Test void testGetUsersBasedOnCriteria() { // 调用原有业务方法,底层会自动操作testUser表 List<User> users = userRepository.getUsersBasedOnCriteria(你的查询参数); // 执行断言校验逻辑正确性 assertEquals(2, users.size()); } }
注意事项
- H2依赖需要添加到test scope,无需修改主项目依赖
- TestUser实体不需要和User完全对齐,仅保留测试逻辑用到的字段即可
- 该方案完全不会侵入原有业务代码,仅测试环境生效,不需要适配原有项目的数据库配置
内容的提问来源于stack exchange,提问作者stackunderflow123
相关产品推荐
相关产品推荐

