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

说明:

我想在Eclipse中使用JUnit 5创建一个JUnit测试(Oxygen 4.7.1a) 。 此JUnit测试应位于名为Test的单独src文件夹中。 但是,由于我是JUnit和Java 9的新手,因此遇到了以下问题。

不想为此使用像Gradle或Maven这样的构建工具。

问题:

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

  • 我需要两个module-info.java文件吗? (每个src文件夹一个)
  • 我的module-info.java文件中需要哪些模块才能使JUnit 5工作?

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

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

为此,您需要使用javacjava提供的新选项:

假设你有以下树:

 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引擎的junit-platform-console-standalone工件,并允许在控制台中运行测试;请参阅用户指南 )

然后你可以编译代码如下:

 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 

并且您可以运行已编译的测试类:

 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.standalone自动模块的名称,派生自Jar清单(与JUnit 5的情况一样),否则来自Jar文件的名称(例如,在JUnit 4的情况下) 。

另请注意,这是Maven在编译和运行unit testing时可能在幕后执行的操作(请参阅此问题以获取手动执行上述操作的等效插件配置)。

如果出于某种原因,您还想模块化您的unit testing怎么办?

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

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

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

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