执行./gradlew clean build时集成测试出现initializationError问题
问题
在Java Spring Boot项目中使用Testcontainers编写了集成测试,单独在IntelliJ运行测试用例或执行./gradlew integrationTest命令均正常,但执行./gradlew clean build进行清理构建时,出现初始化错误。
异常栈信息
IntegrationTest > initializationError FAILED java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:143 Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:800 Caused by: org.springframework.beans.factory.BeanCreationException at ConstructorResolver.java:659 Caused by: org.springframework.beans.BeanInstantiationException at SimpleInstantiationStrategy.java:171 Caused by: java.lang.IllegalStateException at BuildInfoFactory.java:47 Caused by: java.io.FileNotFoundException at ClassPathResource.java:211
项目文件结构
src | |-- main |-- test |-- tests-integration | |-- java |-- resources
build.gradle集成测试任务配置
sourceSets { integrationTest { java { compileClasspath += main.output + test.output runtimeClasspath += main.output + test.output srcDir file("src/tests-integration/java") } resources.srcDir file("src/tests-integration/resources") } } configurations { integrationTestImplementation.extendsFrom testImplementation integrationTestRuntimeOnly.extendsFrom testRuntimeOnly } task integrationTest(type: Test) { useJUnitPlatform() environment "APPLICATION_NAME", "{project_name}" testClassesDirs = sourceSets.integrationTest.output.classesDirs classpath = sourceSets.integrationTest.runtimeClasspath mustRunAfter test finalizedBy jacocoTestReport } integrationTest.configure { onlyIf { !project.hasProperty('skipIntegrationTests') } } check.dependsOn(integrationTest)
解决方案
这个错误的核心原因是:执行clean build时,集成测试任务在Spring Boot的buildInfo文件生成前就启动了。Spring Boot的bootBuildInfo任务会生成META-INF/build-info.properties,而你的集成测试启动Spring上下文时需要读取该文件,clean操作会清空之前的构建产物,导致测试运行时找不到这个资源文件。
修复步骤:
让集成测试任务依赖
bootBuildInfo
在integrationTest任务配置中添加依赖,确保先生成buildInfo文件再执行测试:task integrationTest(type: Test) { // 保留原有配置 dependsOn bootBuildInfo mustRunAfter bootBuildInfo }确保集成测试的classpath包含main的资源输出
调整sourceSets配置,明确将main的resources输出目录加入integrationTest的runtimeClasspath:sourceSets { integrationTest { java { compileClasspath += main.output + test.output runtimeClasspath += main.output + test.output srcDir file("src/tests-integration/java") } resources.srcDir file("src/tests-integration/resources") // 新增:加入main的资源输出 runtimeClasspath += sourceSets.main.resources.outputDir } }验证执行顺序
执行./gradlew clean build时,Gradle会先执行bootBuildInfo生成所需的配置文件,再运行integrationTest,此时测试就能正常读取到build-info.properties文件了。
内容的提问来源于stack exchange,提问作者Anmol Aeron
相关产品推荐
相关产品推荐

