代码之家  ›  专栏  ›  技术社区  ›  NoDataFound

Java模块:Mockito 2.20.0的可访问性问题

  •  2
  • NoDataFound  · 技术社区  · 6 年前

    我正在从Java8迁移到Java10,我正在运行我的测试,由于受包保护的类,测试现在失败了。该版本在maven 3.5.4+Oracle JDK 10.0.2下运行:

    • maven编译器插件3.7.0+asm 6.2
    • maven surefire插件2.22.0+asm 6.2+junit 5.2.0
    • 编译器/surefire都需要asm 6.2,因为这些插件使用的asm版本中存在缺陷。
    • mockito core 2.20.0(但之前在Java8中使用了2.20.0)。
    • 日食光子探测器

    这个项目可以在这里找到 ide-bugs.zip (它位于Eclipse论坛,因为我做了这个。) Topic on Eclipse 对于另一个问题,这一次Eclipse在模块中有局部错误)。

    测试非常简单:我们试图模拟不同的类,使用不同的访问级别——所有这些都在Java 8中工作。

    1. 包保护类
    2. 公共类,但未导出、未打开
    3. 未导出但对Mockito开放的公共类
    4. 未导出但对所有人开放的公共类
    5. 包保护类未导出,但已向Mockito打开
    6. 包保护类未导出,但对所有人开放

    在Java8中,情况1、5和6是相同的(对包的访问受保护)。案例2、案例3和案例4是相同的(接触公众)。

    测试失败,因为Mockito无法:

    • 班级组织。莫基托。科德根。NoteExportedOnToMockitoProtected$MockitoMock$117073031无法访问其超类nodatafound。mjpmsuc。打开。NoteExportedOnToMockitoprotected
    • 班级组织。莫基托。科德根。NoteExportedNotOpenedPublic$MockitoMock$365628885(在未命名模块@0x3f07b12c中)无法访问类nodatafound。mjpmsuc。内部的NoteExportedNotOpenedPublic(在模块nodatafound.mockito_jpms_usecase中),因为模块nodatafound。mockito_jpms_用例不导出nodatafound。mjpmsuc。未命名模块内部@0x3f07b12c

    Mockito实际上有一个自动模块名,但被视为未命名的模块,因为在一个大的“未命名模块”的类路径中找到了所有jar。

    虽然我可以从包保护迁移到非导出包,但我不明白如何解决让我的接口/类对其他模块不可见的问题?

    [编辑]一个月后更新了插件/依赖项的版本,没有结果。

    1 回复  |  直到 6 年前
        1
  •  3
  •   NoDataFound    6 年前

    我在这里找到了问题的部分答案: https://blog.codefx.org/java/java-module-system-tutorial/#Open-Packages-And-Modules

    • Mockito使用反射从模块或类路径访问类。
    • Mockito位于“未命名模块”中,因为Maven将其添加到类路径而不是模块路径中。这就解释了为什么 opens package to org.mockito 从来都不管用:没有 org.mockito 单元
    • Maven Surefire不愿意为允许Mockito访问模块而“打开”模块。
    • 莫基托(不再?)了能够 模拟非私人&非期末班 .无论如何,包保护类都是私有的。错误相当明确:Mockito创建了一个扩展包保护类的类,但现在失败了(它以前工作过,但这可能是因为Mockito在同一个包中创建了类,而不是在被模拟的包中创建的)。

    尽管如此,这在应用程序中给出了一个有问题的配置 pom.xml 每个模块的:

          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
              <argLine>    
      --add-opens nodatafound.mockito_jpms_usecase/nodatafound.mjpmsuc=ALL-UNNAMED
            </configuration>      
          </plugin>
    

    我们需要明确地添加 打开一个未命名的模块 .这不应该在模块信息中完成。java,因为它将模块公开给 全部的 其他不利于封装的模块或罐子。

    这是有问题的,因为:

    • 您需要在pom中指定它。每个包的xml。
    • 它增加了surefire配置的额外负担,我更喜欢简单的配置。
    • 您没有来自IDE的验证;Eclipse将验证模块信息。java标记无效的包。
    • m2e不会向Eclipse JUnit插件传递必要的 <argLine /> 使测试在Eclipse中失败。

    maven方法(在Eclipse中也是如此,据我所知,可能还有Gradle)不允许为测试提供额外的模块信息;例如:让测试依赖性模块化(这可能是通过对每个源模块使用一个专用的测试模块来实现的,就像Eclipse对插件测试所做的那样)。

    推荐文章