Java 无法集成测试gradle多模块Spring引导应用程序

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

在一个Gradle多模块项目中,我无法使用它自己的模块中的引导,因为它需要引用引导模块。我不确定我是否误解了什么。基本结构是:

  • 模块:包含一些REST服务的模块,需要对starter的testImplementation依赖项
  • starter:应用spring引导插件的引导模块,取决于该模块
我已经设置了一个使用Spring Boot 2.3.1.RELEASE和Gradle 6.4的最小示例,配置如下:

./settings.gradle.kts

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