Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我如何打开包并要求依赖于JUnit测试的测试范围模块_Java_Maven_Junit5_Java Platform Module System - Fatal编程技术网

Java 我如何打开包并要求依赖于JUnit测试的测试范围模块

Java 我如何打开包并要求依赖于JUnit测试的测试范围模块,java,maven,junit5,java-platform-module-system,Java,Maven,Junit5,Java Platform Module System,我正在使用类路径将jar项目从Java10迁移到使用Java9 jigsaw模块的Java11。 该项目有JUnit5测试。 测试依赖项由maven在测试范围内提供。 如何打开所有包进行测试,但在模块被其他项目使用时不打开 jar项目只是为其他项目提供了几个类(比如实用程序项目)(因此不需要主类) 该项目在/src/main/java/a/b/c/上获得了5个包。 其中2个应该可以用于使用此jar的项目。 其他3个仅供内部使用(由可访问的用户使用)。 测试位于/src/test/java/a/b

我正在使用类路径将jar项目从Java10迁移到使用Java9 jigsaw模块的Java11。 该项目有JUnit5测试。 测试依赖项由maven在测试范围内提供。 如何打开所有包进行测试,但在模块被其他项目使用时不打开

jar项目只是为其他项目提供了几个类(比如实用程序项目)(因此不需要主类)

该项目在/src/main/java/a/b/c/上获得了5个包。 其中2个应该可以用于使用此jar的项目。 其他3个仅供内部使用(由可访问的用户使用)。 测试位于/src/test/java/a/b/c/。 这些测试在测试范围中提供了依赖项(JUnit、mockito、junt参数),因为这些测试与使用这个jar的项目无关

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
所以现在包1和包3中的公共类应该可以像预期的那样被其他项目访问(我还不能验证这一点)

现在运行测试会导致java.lang.reflect.InAccessibleObject异常:无法使a.b.c.package1.collections.SomeTest()可访问:模块moduleName不会“打开a.b.c.package1”到未命名模块@6a84a97d

当我打开软件包(使用打开)时,一切都很顺利。 但是现在所有的包都打开了。 我希望包2、4和5只能在测试时访问,包1和包3不应该为反射而打开(因此只能导出)

我开始想,既然maven告诉我未命名的模块@6a84a97d,这可能是为测试而创建的模块。 这使我尝试在/src/test/java/处为测试添加一个模块info.java

module moduleNameTest {
requires moduleName; // the code to test
requires java.base;  // java.base could be transient on moduleName

// test dependencies
requires org.junit.jupiter.api;
requires org.junit.jupiter.params;
}
现在,maven(3.5.4)指出:

技术:

  • java openJDK 11
  • mvn 3.5.4
  • JUnit5.3.0
  • Surefire插件3.0.0-M3
  • mockito 2.21.0
如前所述,我希望包2、4和5只能在测试时访问,并且测试将在使用maven构建jar时运行。包1和包3应该导出以在其他项目中使用,但不能打开以进行反射(因此仅导出而不能打开)

如果您需要更多信息,请随时询问

提前谢谢

凯文

“欢迎来到模块化世界的测试”,凯文

我在这里编辑了一篇关于这个主题的博客:

基本上,当涉及白盒测试时,您需要在测试编译测试运行时调整模块系统,以允许测试框架绕过模块系统障碍

我想,你是在正确的轨道上。。。也许Surefire做了错事?想给我一个机会吗?该插件支持开箱即用的黑白盒测试。特别是,当您提供一个
test/java/module info.java
test模块描述符时,这个插件非常出色

有关如何在不接触主模块描述符的情况下组织模块化测试,请参见此“图片”:


src
├── 主要的
│   └── JAVA
│       ├── 福
│       │   ├── PackageFoo.java
│       │   └── PublicFoo.java

│ └── module-info.java如果junit被打包为java9模块,这个问题就可以解决了。你的错误会变成

“无法使a.b.c.package1.collections.SomeTest()可访问:模块moduleName未将a.b.c.package1“打开”到junit5
模块@6a84a97d”

在本例中,您可以将其仅打开到junit5模块(或任何试图在类上使用反射的“命名”测试模块)。由于目前我不认为是这种情况(junit5从java角度属于未命名模块),您的备选选项将是

  • 将测试移动到单独的maven模块。您将有两个maven模块
    yourModule-1.0
    yourModule-tests-1.0
    yourModule-tests-1.0
    将取决于
    yourModule-1.0
    ,因此在maven中它将生成。然后您可以使用
    openmodulenametest{}仅打开测试模块进行反射
    在您的
    模块info.java
    中。您的主模块仍将受到保护

  • 用一些“prefix package”作为测试包的前缀,因此,取而代之的是
    a.b.c.package1.collections.SomeTest()
    您将拥有
    a.b.c.mytests.package1.collections.SomeTest()
    。然后,当您仅打开测试包
    a.b.c.mytests.package1.collections.SomeTest())
    用于反射,同时确保主源代码的安全,因为它仍保留在另一个包中

  • 您现在可以接受这一点,只需使用
    打开a.b.c.package1.collections.SomeTest()
    打开包即可。除非您使用某个共享库,否则可能没有人希望对您的代码使用反射

  • 根据第3点的假设。最简单的方法是打开整个模块进行反射,将其声明为
    openmodulename{}
    ,而不仅仅是“
    moduleName{}
    。这样,每次在尚未打开的包中创建测试时,您不需要调整
    moduleinfo.java


  • 您好@Somuras,谢谢您的回复。似乎我必须在每个包之前添加--add opens和--add reads,而不是说--add opens package1 package2 package3…在弄清楚这一点后,它起作用了。顺便问一下,是否有可能在mvn输出中突出显示测试结果(如java 8中的测试结果),其中223在[INFO][223项测试成功]以绿色突出显示,失败的测试以红色突出显示?不客气。请在此处打开一个关于颜色的问题:提前谢谢。我遇到了与问题中描述的完全相同的问题。但是,答案对我没有帮助。如果我将
    模块信息.java
    也放入
    src/test/java
    中,我会得到错误,即文件是杜普利
    module moduleNameTest {
    requires moduleName; // the code to test
    requires java.base;  // java.base could be transient on moduleName
    
    // test dependencies
    requires org.junit.jupiter.api;
    requires org.junit.jupiter.params;
    }
    
    src/test/java/module-info.java:[3,20] module not found: moduleName
    src/test/java/module-info.java:[4,31] module not found: org.junit.jupiter.api
    src/test/java/module-info.java:[5,31] module not found: org.junit.jupiter.params