一般情况下,没有必要将测试代码模块化(至少我想不到一个有效的理由,也许有人可以给出令人满意的反例)。只有一个
module-info.java
文件可以存在于
src
下的主代码中(毕竟甚至没有必要将您的主代码模块化)。
由于
module-info.java
文件仅存在于主源目录中而不是测试源目录中,因此它在逻辑上不应依赖于JUnit模块。那么现在的问题就变成了如何通过依赖于代表被测试系统和JUnit模块的模块来编译和运行JUnit测试类。
为此,您需要使用
javac
和
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引擎并允许在控制台中运行测试的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
--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
即使在module-info.java
中没有声明,这也使得JUnit成为my.module
所必需的。
org.junit.platform.console.standalone
是自动模块的名称,它源自于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。
如果在模块中包含测试类,则在上述命令中,您不需要
--add-reads
和
--patch-module
。
src/main/java/
和src/test/java/
,因此您可以在一个Maven项目中尝试它-遵循新的“最佳实践”。确实有一个问题https://dev59.com/IlgR5IYBdhLWcg3wZcq1 - Joop Eggen