在没有 Maven 或 Gradle 的情况下将 JUnit 5 与 Java 9 一起使用

Using JUnit 5 with Java 9 without Maven or Gradle

描述:

我想在 Eclipse (Oxygen 4.7.1a) 中使用 JUnit 5 创建一个 JUnit 测试。 这个 JUnit 测试应该在一个名为 Test 的单独的 src 文件夹中。但是,我 运行 遇到了以下问题,因为我是 JUnit 的新手并且 Java 9.

不想为此使用Gradle或Maven等构建工具。

问题:

因为我有两个不同的 src 文件夹,一个用于项目 src,一个用于测试用例:

一般情况下你的测试代码没有必要模块化(至少我想不出一个合理的理由,也许有人能给出一个令人满意的反例)。只有一个 module-info.java 文件可以(毕竟,它甚至不需要模块化你的主代码)在你的主代码中 src.

因为module-info.java文件只会在你的主源目录中,而不在测试源目录中,所以逻辑上它不应该依赖于JUnit模块。所以现在的问题变成了如何编译和 运行 JUnit 测试 class 依赖于模块(代表被测系统)和 JUnit 模块。

为此,您需要使用 javac and java:

提供的新选项

假设您有以下树:

src
    module-info.java (declares a module called "my.module")
    mypackage
        MyClass.java
test_src
    mypackage
        MyClassTest.java
lib/junit-platform-console-standalone.jar

(注意:专门针对 JUnit 5,您可以使用包含核心 JUnit 引擎并允许在控制台中进行 运行ning 测试的 junit-platform-console-standalone 工件;请参阅 the user guide )

那么你可以编译代码如下:

cd root_dir
javac -d mods/my.module src/module-info.java src/mypackage/MyClass.java

cd test_src
javac -d test_out --module-path ../mods;../lib/junit-platform-console-standalone.jar \
--add-modules org.junit.platform.console.standalone,my.module --patch-module my.module=. \
--add-reads my.module=org.junit.platform.console.standalone mypackage/MyClass.java

你可以运行编译测试class:

cd test_src/test_out
java --module-path=../../mods;../../lib/junit-platform-console-standalone.jar \
--add-modules my.module,org.junit.platform.console.standalone \
--add-reads my.module=org.junit.platform.console.standalone \
--patch-module my.module=. \
--add-opens my.module/test=org.junit.platform.console.standalone \ 
org.junit.platform.console.ConsoleLauncher test.MyClassTest

笨拙的命令,但这是不使用 Maven 的代价。我建议您在了解模块路径的概念后阅读命令文档中的这些选项。这里需要注意的重要事项是几个选项:

--patch-module my.module=.

这是必需的,因为示例测试代码与模块 my.module 具有相同的包 (mypackage)。没有它,模块系统会报错。

--add-reads my.module=org.junit.platform.console.standalone

这使得 my.module 需要 junit,即使它没有在 module-info.java 中声明。

org.junit.platform.console.standaloneautomatic 模块的名称 并且派生自 Jar 清单(与 JUnit 5 一样),否则来自Jar 文件(例如,在 JUnit 4 的情况下)。

另请注意,这可能是 Maven 在编译和 运行 单元测试时在幕后所做的(请参阅 this issue 以了解手动执行上述操作的等效插件配置)。

如果出于某种原因,您还想模块化单元测试怎么办?

在这种情况下,由于在上面的示例中单元测试共享同一个包,您可以将它们包含在 my.module 中并向 JUnit 添加一个要求:

module my.module {
    exports mypackage;
    requires org.junit.platform.console.standalone;
}

如果单元测试在不同的包中,您也可以将它们分成两个模块(两个 module-info.java),一个 my.module 和一个 my.test.module,只有后者需要JUnit.

如果你确实在模块中包含测试 classes,那么在上面的命令中,你不需要 --add-reads--patch-module.

将测试单独放在一个模块中的一个原因是六边形架构。测试模块是一个驱动程序适配器,可与其他适配器交换,运行 业务逻辑也是如此。

在我的例子中,我也将在没有 Maven 的情况下使用 jaba 9 来完成。

这是我关于六边形建筑的文章:

https://softwarecampament.wordpress.com/portsadapters/