Micronaut集成postgres与testcontainers时DataSource实例化失败
问题描述
搭建全新Micronaut项目后,执行./gradlew clean build运行初始测试用例时遇到Error instantiating bean of type [javax.sql.DataSource]错误。
复现步骤:
$ mn create-app --inplace --build=gradle_kotlin --jdk=17 --lang=kotlin --test=spock --features=postgres,testcontainers testing | Application created at [...] $ ./gradlew clean build
构建输出错误片段:
> Task :test TestingSpec > initializationError FAILED io.micronaut.context.exceptions.BeanInstantiationException at DefaultBeanContext.java:1921 Caused by: io.micronaut.context.exceptions.BeanInstantiationException at DefaultBeanContext.java:2367 Caused by: io.micronaut.http.client.exceptions.HttpClientResponseException at DefaultHttpClient.java:2237 1 test completed, 1 failed > Task :test FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':test'. > There were failing tests. See the report at: file://[...]/build/reports/tests/test/index.html [...] BUILD FAILED in 14s 22 actionable tasks: 22 executed
测试报告错误详情:
io.micronaut.context.exceptions.BeanInstantiationException: Bean definition [javax.sql.DataSource] could not be loaded: Error instantiating bean of type [javax.sql.DataSource] Message: Not Found Path Taken: DataSource.dataSource(DatasourceConfiguration datasourceConfiguration) --> DataSource.dataSource([DatasourceConfiguration datasourceConfiguration]) at app//io.micronaut.context.DefaultBeanContext.initializeContext(DefaultBeanContext.java:1921) at app//io.micronaut.context.DefaultApplicationContext.initializeContext(DefaultApplicationContext.java:249) at app//io.micronaut.context.DefaultBeanContext.readAllBeanDefinitionClasses(DefaultBeanContext.java:3326) [...]
问题原因与解决办法
问题根源
添加postgres和testcontainers特性后,默认生成的TestingSpec测试类会尝试启动HTTP客户端访问应用端点,但此时因缺少数据源配置,导致应用上下文初始化失败,进而抛出HttpClientResponseException(Not Found),最终引发DataSource实例化错误。
解决步骤
- 补充测试环境数据源配置
在src/test/resources/application-test.yml中添加PostgreSQL测试容器的专属配置:
datasources: default: url: jdbc:tc:postgresql:latest:///testdb driverClassName: org.testcontainers.jdbc.ContainerDatabaseDriver username: test password: test schema-generate: CREATE_DROP dialect: POSTGRES
- 调整测试类逻辑
默认测试类是用于HTTP端点验证的,若当前无需该测试,可修改为验证数据源初始化的逻辑:
package testing import io.micronaut.test.extensions.spock.annotation.MicronautTest import jakarta.inject.Inject import javax.sql.DataSource import spock.lang.Specification @MicronautTest class TestingSpec extends Specification { @Inject DataSource dataSource void "verify datasource is properly initialized"() { expect: dataSource != null dataSource.connection != null } }
- 重新执行构建
再次运行./gradlew clean build,测试即可正常通过。
额外说明
- Testcontainers会通过专用JDBC URL(
jdbc:tc:postgresql:latest:///testdb)自动管理PostgreSQL容器的启动与销毁,无需手动操作容器。 - 若后续需要HTTP端点测试,需确保应用中存在对应控制器,同时保证数据源配置正确,避免上下文启动失败导致端点无法访问。
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

