Production code + Test module-info = Unpossible?

萝らか妹 提交于 2020-01-01 16:54:53

问题


I have a mock class with a trivial implementation of a service I provide from a module. I'm using OpenJDK 11.03, gradle 5.2.1 and IntelliJ 2019.2.

In /main/code/myPackage/myService.java I have:

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

And in my test/code/somePackage/myMockService I have

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

In my main/code/module-info.java I have

module myModule {
    exports somePackage;
}

I've tried several variations on a test/code/module-info.java, without success. For example:

// "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
}

The above module-info spews errors about how "module name myTestModule does not match expected name myModule", "package 'myPackage' is not visible" (from myMockModule.java), explaining "package myPackage is declared in module myModule but module myTestModule does not read it"

On the other hand, with the following module-info, I get a different batch of errors (below the code)

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

Without a requires myModule;, every reference to the main code branch from my test code gives an "error: cannot find symbol". With a requires myModule;, I get an "error: cyclic dependence involving myModule".

So... my tests can't be in a different module. AND they can't be the same module! [long string of expletives deleted]

  • How do I introduce a mock version of a service in test code rather than creating an entirely different module/gradle sub-project?

  • Or is this simply a case where that's not possible, and while you can have a separate test module-info, you can't do much with it?

  • Or is there some way to dynamically load things at runtime such that I don't have to put every little mock service in any module-info, test or otherwise? Such that ServiceLoader.load will find them. Hmm... perhaps extend ServiceLoader and wrap its usage in main code such that it'll use the right one either in production code or test code...


回答1:


a) Welcome to "Testing in the Modular World"!

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

Having one or more dedicated test modules is good. With all bells-and-whistles, read module-info.java declarations. Those test modules are your main modules' first clients. Just make sure, that your build tool packages all main modules before compiling and running the test modules. Otherwise you don't test your main modules as close as possible to reality -- others will consume your main modules as JAR files. So should you. This solves all issues with services and multi-release JARs as well.

Now the interesting part: in-module testing, also named white box testing. Or how do test types residing non-exported packages or package-private types in exported packages? Either use a build that knows how to patch test modules into main modules (or vice versa) at test compile and/or test runtime. Like pro or Bach.java (which I maintain), or in your case of using Gradle, see b)elow part of this answer.

b) Gradle and Java main, test, ... modules are not friends out-of-the-box, yet

Best plugin-based solution: https://github.com/java9-modularity/gradle-modules-plugin -- which honors the pass theses java command line options at test runtime module-info.test configuration file (which I invented). Here you basically desribe your test module requirements via verbose command line options, although a perfect DSL already exists: module-info-java ... loop back to a) and the module-aware build tools.

c) IntelliJ IDEA and Java test modules are ... improving!

  • https://youtrack.jetbrains.com/issue/IDEA-171419 module-info.java support in 2019.3
  • https://youtrack.jetbrains.com/issue/IDEA-222831 module-info.test support, soon?


来源:https://stackoverflow.com/questions/58979522/production-code-test-module-info-unpossible

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!