Eclipse:Gradle 源文件夹迁移破坏了 JUnit 测试资源
Eclipse: Gradle source folder migration breaks JUnit test resources
我重构了一个 Eclipse 项目,使用 Java 11.0.10 来匹配 Gradle 的默认源和资源文件夹,而不是 Eclipse 的源和资源文件夹,如下所示:
eclipse Gradle
src -> src/main/java
resources -> src/main/resources
test -> src/test/java
testResources -> src/test/resources
我将源和资源相应地移动到文件夹中。
当我在 JUnit 测试中访问测试资源时,例如 TestClass.class.getResource("/my/package/mytestresource.xml")
它 returns [ProjectFolder]/src/main/resources/my/package/mytestresource.xml
而不是 [ProjectFolder]/src/test/resources/my/package/mytestresource.xml
。测试在 Eclipse 的 JUnit 启动器上运行。
TestClass.java 位于 [ProjectFolder]/src/test/my/package
,测试资源位于 [ProjectFolder]/src/test/resources/my/package/mytestresource.xml
。
这在重构之前非常有效。
如何告诉 Eclipse 和 JUnit 将输出路径合并在一起?或者我可以告诉 Eclipse 使用 2 个输出路径吗?
以前 build.gradle
包含这个(已完全删除):
sourceSets {
main {
java {
srcDirs = ['src']
}
resources {
srcDirs = ['resources']
}
}
test {
java {
srcDirs = ['src', 'test']
}
resources {
srcDirs = ['resources', 'testResources']
}
}
}
.classpath
变更前:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="bin/test" path="test">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="resources">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="testResources">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>
.classpath
修改后:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="bin/main" path="src/main/java">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/main" path="src/main/resources">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/java">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/resources">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>
我使用以下软件:
Windows 10 Version 2004
eclipse JDT 2021-03
Buildship 3.1.5
Gradle 6.4.1
JUnit Jupiter 5.7.0
我找到了两个解决此问题的方法:
在项目中添加gradleeclipse插件并在项目的.classpath
文件中操作classpathentry
:
apply plugin: 'eclipse'
eclipse {
classpath {
file {
whenMerged {
entries.each { source ->
if (source.kind == 'src' && source.path.contains('src/main')) {
source.entryAttributes.put("test", "true")
source.output="bin/test"
}
}
}
}
}
}
或者
使用 Gradle 的默认源和资源文件夹在 gradle 构建中重新引入 sourceSets
。
sourceSets {
main {
java {
srcDirs = ['src/main/java']
}
resources {
srcDirs = ['src/main/resources']
}
}
test {
java {
srcDirs = ['src/main/java', 'src/test/java']
}
resources {
srcDirs = ['src/main/resources', 'src/test/resources']
}
}
}
我不确定为什么在 eclipse 中会发生这种情况,但至少它再次起作用了。
我重构了一个 Eclipse 项目,使用 Java 11.0.10 来匹配 Gradle 的默认源和资源文件夹,而不是 Eclipse 的源和资源文件夹,如下所示:
eclipse Gradle
src -> src/main/java
resources -> src/main/resources
test -> src/test/java
testResources -> src/test/resources
我将源和资源相应地移动到文件夹中。
当我在 JUnit 测试中访问测试资源时,例如 TestClass.class.getResource("/my/package/mytestresource.xml")
它 returns [ProjectFolder]/src/main/resources/my/package/mytestresource.xml
而不是 [ProjectFolder]/src/test/resources/my/package/mytestresource.xml
。测试在 Eclipse 的 JUnit 启动器上运行。
TestClass.java 位于 [ProjectFolder]/src/test/my/package
,测试资源位于 [ProjectFolder]/src/test/resources/my/package/mytestresource.xml
。
这在重构之前非常有效。
如何告诉 Eclipse 和 JUnit 将输出路径合并在一起?或者我可以告诉 Eclipse 使用 2 个输出路径吗?
以前 build.gradle
包含这个(已完全删除):
sourceSets {
main {
java {
srcDirs = ['src']
}
resources {
srcDirs = ['resources']
}
}
test {
java {
srcDirs = ['src', 'test']
}
resources {
srcDirs = ['resources', 'testResources']
}
}
}
.classpath
变更前:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="bin/test" path="test">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="resources">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="testResources">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>
.classpath
修改后:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="bin/main" path="src/main/java">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/main" path="src/main/resources">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/java">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/resources">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>
我使用以下软件:
Windows 10 Version 2004
eclipse JDT 2021-03
Buildship 3.1.5
Gradle 6.4.1
JUnit Jupiter 5.7.0
我找到了两个解决此问题的方法:
在项目中添加gradleeclipse插件并在项目的
.classpath
文件中操作classpathentry
:apply plugin: 'eclipse' eclipse { classpath { file { whenMerged { entries.each { source -> if (source.kind == 'src' && source.path.contains('src/main')) { source.entryAttributes.put("test", "true") source.output="bin/test" } } } } } }
或者
使用 Gradle 的默认源和资源文件夹在 gradle 构建中重新引入
sourceSets
。sourceSets { main { java { srcDirs = ['src/main/java'] } resources { srcDirs = ['src/main/resources'] } } test { java { srcDirs = ['src/main/java', 'src/test/java'] } resources { srcDirs = ['src/main/resources', 'src/test/resources'] } } }
我不确定为什么在 eclipse 中会发生这种情况,但至少它再次起作用了。