Java 无法集成测试gradle多模块Spring引导应用程序
在一个Gradle多模块项目中,我无法使用它自己的模块中的引导,因为它需要引用引导模块。我不确定我是否误解了什么。基本结构是:Java 无法集成测试gradle多模块Spring引导应用程序,java,spring,spring-boot,gradle,multi-module,Java,Spring,Spring Boot,Gradle,Multi Module,在一个Gradle多模块项目中,我无法使用它自己的模块中的引导,因为它需要引用引导模块。我不确定我是否误解了什么。基本结构是: 模块:包含一些REST服务的模块,需要对starter的testImplementation依赖项 starter:应用spring引导插件的引导模块,取决于该模块 我已经设置了一个使用Spring Boot 2.3.1.RELEASE和Gradle 6.4的最小示例,配置如下: ./settings.gradle.kts rootProject.name=“spr
- 模块:包含一些REST服务的模块,需要对starter的testImplementation依赖项
- starter:应用spring引导插件的引导模块,取决于该模块
rootProject.name=“spring多模块集成测试”
包括(“起动器”、“模块”)
./build.gradle.kts
子项目{
存储库{
jcenter()
}
依赖关系{
应用(plugin=“java库”)
“测试实施”(“junit:junit:4.12”)
}
}
./starter/build.gradle.kts
插件{
id(“org.springframework.boot”)版本“2.3.1.RELEASE”
}
依赖关系{
实施(项目(“:模块”))
}
/模块/build.gradle.kts
起动机模块仅包含一个单独的“起动机”类,参考模块:
公共类初学者{
公共字符串信息(){return“starter”;}
公共静态void main(字符串[]args){
System.out.println(新启动程序().info()+”和“+新模块().info());
}
}
模块模块(*我应该为此模块选择其他名称)仅包含此实现类:
公共类模块{
公共字符串信息(){return“module”;}
}
此外,模块还有以下测试类进行集成测试:
公共类集成测试
{
@测试公共void testSomeLibraryMethod(){
final ByteArrayOutputStream out=新ByteArrayOutputStream();
系统放样(新打印流(out));
main(新字符串[0]);
assertEquals(“启动器和模块”,out.toString());
}
}
在应用“/starter/build.gradle.kts”中的spring引导插件之前,此代码运行良好。当在shell上发布任务“清洁测试”时,我得到:
❯ ./gradlew clean test
> Task :module:test FAILED
de.kramhal.multi.IntegrationTest > testSomeLibraryMethod FAILED
java.lang.NoClassDefFoundError at IntegrationTest.java:17
Caused by: java.lang.ClassNotFoundException at IntegrationTest.java:17
1 test completed, 1 failed
当在IDE中执行测试时(确切地说是IntelliJ),不会出现此问题
我已经尝试使用本文(以及其他几个答案)中建议的spring依赖关系管理,但没有成功
我做错了什么?首先,我建议您重新构建项目,这样您就不会有循环依赖关系。现在,为了构建
starter
,您需要构建模块
。为了测试模块
,您需要构建启动器
。格拉德尔能做到,但它通常是一种气味
在故障排除方面:当您遇到这样的测试失败时,请查看测试报告,因为它具有完整的堆栈跟踪。您应该看到,它抱怨找不到Starter
类(原因:java.lang.ClassNotFoundException:de.kramhal.multi.Starter
),这是Starter
模块中的原因
您提到了spring依赖项管理
插件,但它只与管理Maven依赖项相关,而不是像这样的项目依赖项。所以这在这里没有帮助
我不完全确定这是否是特定于Windows的,因为我记得在很久以前有很多类的时候,有一些关于性能的讨论。但是我相信java库
插件会在其他项目中查找jar文件,而不是用于编译类的文件夹。这对您来说是一个问题,因为springboot
插件默认情况下会禁用标准jar
任务,而是通过bootJar
任务创建一个“fat”jar文件。因为您既需要fat jar来打包独立运行的应用程序,也需要普通jar来将其作为依赖项使用,所以您需要对starter
项目(Kotlin DSL)进行一些调整:
任务{
罐子{
启用=真
}
布特贾尔{
archiveClassifier.set(“启动”)
}
}
这将启用普通jar文件,但由于名称与bootJar
任务生成的名称冲突,因此需要重命名其中一个。我选择重命名bootJar
one
我不知道为什么IntelliJ中的测试适用于您,因为默认情况下,它应该将所有内容委托给Gradle。但是,也许您有一个旧版本,或者做了一些手动配置,让IntelliJ编译和运行您的测试。首先,我建议重新构造您的项目,这样您就不会有循环依赖关系。现在,为了构建
starter
,您需要构建模块
。为了测试模块
,您需要构建启动器
。格拉德尔能做到,但它通常是一种气味
在故障排除方面:当您遇到这样的测试失败时,请查看测试报告,因为它具有完整的堆栈跟踪。您应该看到,它抱怨找不到Starter
类(原因:java.lang.ClassNotFoundException:de.kramhal.multi.Starter
),这是Starter
模块中的原因
您提到了spring依赖项管理
插件,但它只与管理Maven依赖项相关,而不是像这样的项目依赖项。所以这在这里没有帮助
我不完全确定这是否是特定于Windows的,因为我记得在很久以前有很多类的时候,有一些关于性能的讨论。但是我相信java库
插件会在其他项目中查找jar文件,而不是用于编译类的文件夹。这对您来说是一个问题,因为spring引导
pl
❯ ./gradlew clean test
> Task :module:test FAILED
de.kramhal.multi.IntegrationTest > testSomeLibraryMethod FAILED
java.lang.NoClassDefFoundError at IntegrationTest.java:17
Caused by: java.lang.ClassNotFoundException at IntegrationTest.java:17
1 test completed, 1 failed