java - 如何在同一个模块内进行测试?

标签 java junit5 java-module

在这个项目中,我有一个模块化设置。有一个父级,其中有两个模块。

这是来自parent-pom.xml的片段:

<modules>
    <module>moduleA</module>
    <module>moduleB</module>
</modules>

两个模块都有一个 module-info.java。这是 moduleB 的 module-info.java:

module moduleB {
    requires spring.web;
    requires static lombok;
    requires java.validation;
    requires swagger.annotations;
    requires slf4j.api;
    exports com.example.service
}

在 moduleB 中,有主文件夹和测试文件夹,就像任何常规 java 项目一样。在测试文件夹中,有一个 JUnit5 测试,它试图测试同一包中但在 src 文件夹中的服务。

在尝试执行此操作时,我收到以下错误消息:

module moduleB does not "opens com.example.service" to unnamed module @67205a84

据我了解,所有不属于模块的依赖项都将打包在“未命名”模块中。在本例中模块@67205a84。我期望在这个模块中包含像 Mockito 这样的东西,我只将其用于测试。如果我的这个假设有误,请纠正我。

当我打开 moduleB 时(通过在 moduledeclaration 之前添加“open”一词),测试运行顺利。但显然这不是我想要的。

所以我的问题实际上是:我可以打开未命名的模块以便我的测试可以运行,但我的模块对于除测试之外的任何内容都保持关闭状态吗?

这是目录结构的简化概述。

- parent
  |
  -> - pom.xml
     - moduleA
     - moduleB
       |
       -> - pom.xml
          - src
            |
            -> - main
                 |
                 -> - java
                      |
                      -> - module.info
                         - com.example.service
                           |
                           -> - ModuleBService.java
               - test
                 | 
                 -> - java
                      | 
                      -> - com.example
                           |
                           -> - Application.java
                         - com.example.service
                           | 
                           -> - ModuleBServiceTest.java

事实证明,Application.class 的位置是相关的。我试图测试的模块没有用 @SpringbootApplication 注释的类,因为它只是一个库。为了测试它的功能,我必须在测试中启动一个 SpringbootApplication 。当 Application.java 与 ModuleBServiceTest.java 位于同一包中时,一切正常。当我将其移出到另一个包中时,会出现上面的错误消息。这是为什么?

最佳答案

您可以做的是配置surefire插件以将模块打开到您的moduleB的POM中的未命名模块

<build>
  <plugins>
    <plugin>
      <artifactId>maven-surefire-plugin</artifactId>
      <configuration>
        <argLine>
          <!-- Allow access to the tests during test time -->
          --add-opens moduleB/com.example.service=ALL-UNNAMED
          <!-- Add export to test-util classes to moduleC if it wants to reuse these -->
          --add-exports moduleB/com.example.service.test.util=moduleC
          <!-- Prevent any illegal access to modules -->
          --illegal-access=deny
        </argLine>
      </configuration>
    </plugin>
  </plugins>
</build>

我还添加了一个示例,您可以在其中将一些测试实用程序类显式导出到另一个模块,以防它想要访问这些

As it turns out, the location of the Application.class is relevant. The module I am trying to test does not have a class annotated with @SpringbootApplication, because it's just a library. To test it's functionality, I have to start a SpringbootApplication in test. When the Application.java is in the same package as the ModuleBServiceTest.java, all is well. When I move it out in another package the error-message from above occurs. Why is that?

据我所知,Spring Boot 将扫描其包和任何子包中的组件、服务等,并将这些自动添加到其配置中。如果应用程序不直接位于祖先路径中,它可能无法找到您的测试类,但老实说,给出的信息有点有限。

关于java - 如何在同一个模块内进行测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62065487/

相关文章:

java - Junit 5,Spring 应用程序上下文未在 @DirtiesContext 上关闭

java - 在 Spring、Hibernate 中访问用户数据

java - Dockerized Spring Boot 应用程序中的 FileSystemNotFoundException

java - Android Studio 无法启动,无法创建 JVM

java - 在 SpringBoot 中使用 Testcontainers 进行 Spring Data Elasticsearch 集成测试

java - 以更智能的方式在 Junit 5(或其他测试 Java 库)中使用数组参数化

java - 从 Java 8 迁移到 Java 11。在运行时,是否可以从 Java 8 中编译的库中的类文件访问 JDK 内部 API?

java - 如何替换 --add-modules java.xml.ws

java - 如何使用 Selenium Webdriver 从 Angular 应用程序获取所有 WebElement?

Java 模块化与依赖注入(inject)