SpringBootTest单元测试报错:无法加载core模块多数据源
问题背景
我们将多微服务共用的JPA层抽离为core Jar模块(由AWS CodeArtifact管理),在运行依赖该模块的Spring Boot定时任务应用的@SpringBootTest单元测试时,抛出以下错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception with message: dataSource or dataSourceClassName or jdbcUrl is required.
core模块为多Schema配置了多个数据源Bean(Spring Boot父依赖版本为3.2.0-SNAPSHOT):
@Bean(name = "primaryDataSource") @Primary @ConfigurationProperties(prefix = "spring.primary-datasource") public DataSource primaryDataSource(){ return DataSourceBuilder.create().build(); } @Bean(name = "secondDataSource") @ConfigurationProperties(prefix = "spring.second-datasource") public DataSource secondDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "thirdDataSource") @ConfigurationProperties(prefix = "spring.third-datasource") public DataSource thirdDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "fourthDataSource") @ConfigurationProperties(prefix = "spring.fourth-datasource") public DataSource fourthDataSource() { return DataSourceBuilder.create().build(); }
应用运行时正常,但测试上下文无法加载数据源,复制core模块的src/main/resources到src/test/resources无效。
解决方案
1. 补全测试环境的数据源配置
测试时,消费应用的测试配置文件(如application-test.properties/application-test.yml)缺少spring.primary-datasource等前缀的数据源属性,导致DataSourceBuilder无法构建数据源。
在消费应用的src/test/resources下的配置文件中添加测试用数据源配置(推荐用H2内存数据库):
# 主数据源 spring.primary-datasource.url=jdbc:h2:mem:primary;DB_CLOSE_DELAY=-1 spring.primary-datasource.username=sa spring.primary-datasource.password= spring.primary-datasource.driver-class-name=org.h2.Driver # 第二个数据源 spring.second-datasource.url=jdbc:h2:mem:second;DB_CLOSE_DELAY=-1 spring.second-datasource.username=sa spring.second-datasource.password= spring.second-datasource.driver-class-name=org.h2.Driver # 其他数据源同理补充
2. 排除冲突的自动配置类
Spring Boot自动配置会尝试创建默认的EntityManagerFactory,但自定义多数据源后,测试时自动配置可能因找不到默认数据源报错。
如果测试不需要JPA相关功能,可在@SpringBootTest中排除自动配置类:
@SpringBootTest(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
若测试需要操作数据库,仅排除默认的JPA配置类:
@SpringBootTest(exclude = HibernateJpaConfiguration.class)
3. 确保core模块配置类被扫描
检查消费应用的测试类是否正确扫描core模块的配置包,可通过scanBasePackages指定扫描路径:
@SpringBootTest(scanBasePackages = {"com.your.core.config.package", "com.your.app.package"})
4. 验证core模块打包完整性
确认core模块的Maven/Gradle配置未过滤配置类,比如maven-jar-plugin未排除配置类所在包,确保配置类被正确打包进Jar。
原因说明
应用运行时正常是因为主配置文件包含了所有数据源属性,而测试时默认使用的测试配置文件缺失这些属性;同时测试上下文的自动配置逻辑与运行时存在差异,导致无法构建数据源。复制core模块的测试资源无效,因为测试时是消费应用的测试上下文加载配置,而非core模块自身的测试上下文。
内容的提问来源于stack exchange,提问作者Bradley D

