java - 模块化项目中测试代码的实用打包
问题描述
我一直在思考 Java 模块系统,并且有一个问题在这里没有解决。我又摸索了一下,找到了答案,所以我想我会发布信息,以防它缩短其他人的搜索时间。
传统上,测试保存在与项目代码主体不同的源代码树中,因此测试二进制文件很容易从最终项目的最终交付物中分离出来。我不确定如何使用模块系统来实现这一点,但事实证明它仍然很容易。
我们的(可能是多模块的)模块项目的源代码通常布局为"sources/MyModule/src/main/java"
. 然后,我们将使用--module-source-path
set to指定编译"source/*/src/main/java"
(请注意,引号很重要,否则您的操作系统将尝试扩展星号。您不希望这样,您想将其交给javac
)。如果源代码下还有其他模块,只要它们的整体结构相同,只是名称不同,就会被找到并编译。但是,事实证明我们似乎能够将一个模块拆分为两棵树。所以,这个源布局:
.
└── sources
├── ModOne
│ ├── java
│ │ ├── module-info.java
│ │ └── pkg
│ │ └── Prod.java
│ └── test
│ └── pkg
│ └── Test.java
└── ModTwo
└── java
├── module-info.java
└── p2
└── RunMe.java
使用此命令一次性正确编译:
javac -d out --module-source-path "./sources/*/java:./sources/*/test" --module ModTwo,ModOne
请注意,我没有指定 ModOne 测试部分不会被编译,但只要我明确这样做,它就会被发现,并且输出创建了这个目录树:
.
├── out
│ ├── ModOne
│ │ ├── module-info.class
│ │ └── pkg
│ │ ├── Prod.class
│ │ └── Test.class
│ └── ModTwo
│ ├── module-info.class
│ └── p2
│ └── RunMe.class
RunMe 中的 main 方法是这样执行的:
java --module-path out --module ModTwo/p2.RunMe
在我的 Test 类中实际上有一个 main,它运行并成功地对 ModOne 的其余代码具有包级别的访问权限。
树中源文件的内容:
sources/ModOne/java/module-info.java:
module ModOne {
exports pkg;
}
sources/ModOne/java/pkg/Prod.java:
package pkg;
public class Prod {
public static String name = "Fred";
}
sources/ModOne/test/pkg/Test.java:
package pkg;
public class Test {
public static void main(String [] args) {
System.out.println("Value is " + Prod.name);
}
}
sources/ModTwo/java/module-info.java:
module ModTwo {
requires ModOne;
}
sources/ModTwo/java/p2/RunMe.java:
package p2;
public class RunMe {
public static void main(String [] args) {
System.out.println("Pulling from ModOne I get name is " + pkg.Prod.name);
}
}
解决方案
在现实生活中还有更多的东西,只要想想你的测试源必须看到的测试框架(例如,junit),但你的主要源不应该可以访问它。
在最近的题为“调整你的模块”的演示文稿中,我将此用例作为主要示例:
- 幻灯片:https ://www.eclipsecon.org/sites/default/files/slides/TweakYourModules_ECE_2019_0.pdf
- 录音:https ://www.youtube.com/watch?v=UUQoQtKgaWc
简而言之:
- 主要和测试需要两个不同参数的编译
- 依赖关系的连接是通过诸如等选项完成
--patch-module
的--add-reads
。
好消息:像 Maven 或 Eclipse 这样的工具会自动为您完成大部分工作。
推荐阅读
- python - 如何将异步状态从一个函数保留到另一个函数
- list - 关于安排和分配组的 Prolog 初学者问题
- javascript - React 回调函数不起作用如何解决?
- postgresql - 如何使用自定义参数组对 CloudFormation 中的 Aurora Postgres 进行主要版本升级?
- php - 如果模板本身不需要它(例如模板没有 mc:edit),那么 template_content 应该是什么?
- java - 在Android中通过蓝牙发送字符串
- r - 使用 openxlsx R 包迭代列以将它们更改为百分比
- laravel - 从上下文调用私有 Instamojo\Instamojo::__construct()
- c# - 关于参数的 C# 泛型委托声明
- python - 如何映射响应并将其保存到 Django 中的数据库?