8

我有一个模拟类,其中包含我从模块提供的服务的简单实现。我正在使用 OpenJDK 11.03、gradle 5.2.1 和 IntelliJ 2019.2。

/main/code/myPackage/myService.java我有:

package myPackage;
class myService {
   public abstract void someFunction();
}

在我的test/code/somePackage/myMockService我有:

package myPackage;
// no import, they're in the same package.
class myMockService extends myService {
   @Override
   public void someFunction() { System.out.prinln("Hello World"); }
}

在我的main/code/module-info.java我有:

module myModule {
    exports somePackage;
}

我在 a 上尝试了几种变体test/code/module-info.java,但均未成功。例如:

// "open module" lets anyone use reflection within (mostly JUnit 5 in my case)
import myPackage.myService;
import myPackage.myMockService;
open module myTestModule { 
    exports myPackage;
    provides myService with myMockService
}

以上module-info.java关于“模块名称 myTestModule 与预期名称 myModule 不匹配”、“包 'myPackage' 不可见”(来自 myMockModule.java)的错误,解释了“包 myPackage 在模块 myModule 中声明但模块 myTestModule 未读取它"

另一方面,使用以下内容module-info.java,我得到了不同批次的错误(在代码下方)

import myPackage.myService;
import myPackage.myMockService;
open module myModule {
    provides myService with myMockService;
}

如果没有requires myModule;,我的测试代码中对主代码分支的每次引用都会给出“错误:找不到符号”。 使用a requires myModule;,我得到一个“错误:涉及 myModule 的循环依赖”。

所以......我的测试不能在不同的模块中。而且它们不能是同一个模块![删除一长串脏话]

  • 如何在测试代码中引入服务的模拟版本,而不是创建完全不同的模块/gradle 子项目?

  • 或者这只是一个不可能的情况,虽然你可以有一个单独的测试模块信息,但你不能用它做很多事情?

  • 或者有什么方法可以在运行时动态加载东西,这样我就不必把每一个小模拟服务都放在任何模块信息、测试或其他地方?这样ServiceLoader.load()就会找到他们。嗯......也许ServiceLoader在主代码中扩展和包装它的用法,以便它在生产代码或测试代码中使用正确的......

4

1 回答 1

12

a) 欢迎来到“模块化世界中的测试”!

TL;DR https://sormuras.github.io/blog/2018-09-11-testing-in-the-modular-world.html

拥有一个或多个专用测试模块是很好的。带着所有的花里胡哨,阅读module-info.java声明。这些测试模块是您的主要模块的第一个客户。只需确保您的构建工具在编译和运行测试模块之前打包所有主要模块。否则,您不会尽可能接近实际地测试您的主模块——其他人会将您的主模块作为 JAR 文件使用。你也应该这样。这也解决了服务和多版本 JAR 的所有问题。

现在有趣的部分:模块内测试,也称为白盒测试。或者如何测试驻留在导出包中的非导出包或包私有类型的类型?要么使用知道如何在测试编译和/或测试运行时将测试模块修补到主模块(反之亦然)的构建。像proBach.java(我维护),或者在您使用 Gradle 的情况下,请参阅此答案的 b)elow 部分。

b) Gradle 和 Java main, test, ... 模块还不是开箱即用的朋友

最佳基于插件的解决方案:https ://github.com/java9-modularity/gradle-modules-plugin——它在测试运行时配置文件(我发明的)中尊重通过这些 java 命令行选项。 module-info.test在这里,您基本上通过详细的命令行选项描述您的测试模块要求,尽管已经存在完美的 DSL:module-info-java... 循环回 a) 和模块感知构建工具。

c) IntelliJ IDEA 和 Java测试模块正在......改进!

于 2019-11-22T08:28:34.380 回答