首页 > 解决方案 > 模块化项目中测试代码的实用打包

问题描述

我一直在思考 Java 模块系统,并且有一个问题在这里没有解决。我又摸索了一下,找到了答案,所以我想我会发布信息,以防它缩短其他人的搜索时间。

传统上,测试保存在与项目代码主体不同的源代码树中,因此测试二进制文件很容易从最终项目的最终交付物中分离出来。我不确定如何使用模块系统来实现这一点,但事实证明它仍然很容易。

我们的(可能是多模块的)模块项目的源代码通常布局为"sources/MyModule/src/main/java". 然后,我们将使用--module-source-pathset 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);
  }
}

标签: javaunit-testingjava-9java-module

解决方案


在现实生活中还有更多的东西,只要想想你的测试源必须看到的测试框架(例如,junit),但你的主要源不应该可以访问它。

在最近的题为“调整你的模块”的演示文稿中,我将此用例作为主要示例:

简而言之:

  1. 主要和测试需要两个不同参数的编译
  2. 依赖关系的连接是通过诸如等选项完成--patch-module--add-reads

好消息:像 Maven 或 Eclipse 这样的工具会自动为您完成大部分工作。


推荐阅读