如何为JpaRepository创建测试Bean?Spring Boot迁移测试难题
解决旧Hibernate DAO测试中自动装配JpaRepository的问题
下面几个实用方案,能帮你在半迁移状态下搞定这个问题:
方案1:在旧测试类中直接启用JPA仓库扫描
不用依赖@DataJpaTest,直接在旧测试类里添加JPA仓库扫描和必要配置,同时保留原有Hibernate DAO的配置:
@RunWith(SpringRunner.class) @ContextConfiguration(classes = {OldHibernateDaoConfig.class}) // 保留原有的Hibernate DAO配置类 @EnableJpaRepositories(basePackages = "com.yourproject.repositories") // 指定JpaRepository所在包路径 @Transactional public class OldHibernateDaoTest { // 原有旧DAO的注入 @Autowired private UserHibernateDao userDao; // 现在可以直接自动装配JpaRepository了 @Autowired private OrderJpaRepository orderRepo; // 测试方法示例 @Test public void testDaoAndRepoInteraction() { // 调用旧DAO操作数据 User user = userDao.createUser("test"); // 调用新JpaRepository关联操作 Order order = new Order(user); orderRepo.save(order); // 断言验证 assertNotNull(order.getId()); } }
如果旧配置里没有EntityManagerFactory和JpaTransactionManager,需要补充一个核心JPA配置类:
@TestConfiguration public class JpaCoreTestConfig { @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource); em.setPackagesToScan("com.yourproject.entities"); // 实体类所在包 em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); // 可按需添加Hibernate属性,比如ddl-auto=create-drop Properties props = new Properties(); props.put("hibernate.hbm2ddl.auto", "create-drop"); em.setJpaProperties(props); return em; } @Bean public JpaTransactionManager transactionManager(EntityManagerFactory emf) { return new JpaTransactionManager(emf); } }
把这个配置类也加入到旧测试类的@ContextConfiguration中即可。
方案2:创建混合测试配置类
把旧Hibernate配置和JPA配置整合到一个测试配置类里,让旧测试类直接引用这个混合配置:
@TestConfiguration @Import(OldHibernateDaoConfig.class) // 导入原有Hibernate DAO配置 @EnableJpaRepositories(basePackages = "com.yourproject.repositories") public class MixedTestConfig { // 这里放入上面JpaCoreTestConfig里的EntityManagerFactory和TransactionManager配置 }
然后旧测试类简化为:
@RunWith(SpringRunner.class) @ContextConfiguration(classes = {MixedTestConfig.class}) @Transactional public class OldHibernateDaoTest { @Autowired private UserHibernateDao userDao; @Autowired private OrderJpaRepository orderRepo; // 测试逻辑... }
方案3:复用Testcontainers数据库配置
如果新测试用了Testcontainers,可把数据库配置抽成公共类,让旧测试复用同一容器数据库,避免重复配置:
@TestConfiguration public class TestContainerDbConfig { @Bean public PostgreSQLContainer<?> postgreSQLContainer() { PostgreSQLContainer<?> container = new PostgreSQLContainer<>("postgres:14-alpine"); container.start(); return container; } @Bean public DataSource dataSource(PostgreSQLContainer<?> container) { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(container.getDriverClassName()); dataSource.setUrl(container.getJdbcUrl()); dataSource.setUsername(container.getUsername()); dataSource.setPassword(container.getPassword()); return dataSource; } }
把这个配置类导入到混合测试配置中,就能让旧测试和新测试共享同一个数据库容器,保证数据环境一致。
关键注意事项
- 确保Hibernate的
SessionFactory和JPA的EntityManagerFactory使用同一个DataSource,避免连接不同数据库。 - 测试类添加
@Transactional,让测试结束后自动回滚数据,避免污染测试环境。 - 如果旧配置中已有
DataSource,直接复用即可,无需重复创建。
内容的提问来源于stack exchange,提问作者Daniel Pop
相关产品推荐
相关产品推荐

