使用JPMS的maven中的Mockito无法访问带有修饰符"private"的类成员. [英] Mockito in maven using JPMS cannot access a member of class with modifiers "private"

查看:141
本文介绍了使用JPMS的maven中的Mockito无法访问带有修饰符"private"的类成员.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将代码库迁移到Java 11和JPMS/Jigsaw,并且在模拟时遇到了一些麻烦.

I am migrating a codebase to Java 11 and JPMS / Jigsaw and am having some trouble with mocking.

这是我要运行的测试.

import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class DbTest {

    @Mock
    private Connection connection;

    @Mock
    private PreparedStatement preparedStatement;

    @Captor
    private ArgumentCaptor<Timestamp> dateCaptor;

    @Test
    public void setTimestamp_instant() throws SQLException {
        Instant inputTime = Instant.parse("2018-03-12T10:25:37.386Z");
        when(connection.prepareStatement(anyString())).thenReturn(preparedStatement);
        PreparedStatement preparedStatement = connection.prepareStatement("UPDATE fakeTable SET time = ? WHERE TRUE");
        RowPack rowPack = new RowPack(preparedStatement, DatabaseType.MYSQL);
        rowPack.setTimestamp(inputTime);
        verify(preparedStatement).setTimestamp(anyInt(), dateCaptor.capture(), Mockito.any(Calendar.class));
    }
}

在Eclipse中运行此测试时,该测试通过了,但是当我通过maven运行该测试时,它失败了,因为Mockito无法使用反射找到某些资源.

When running this test in Eclipse it passes but when I run it through maven it fails due to mockito being unable to find some resources using reflection.

org.mockito.exceptions.base.MockitoException: Problems setting field connection annotated with @org.mockito.Mock(name="", stubOnly=false, extraInterfaces={}, answer=RETURNS_DEFAULTS, serializable=false, lenient=false)
Caused by: java.lang.IllegalAccessException: class org.mockito.internal.util.reflection.ReflectionMemberAccessor cannot access a member of class foo.bar.DbTest (in module foo.bar) with modifiers "private"

我正在使用Surefire 3.0.0-M5,junit 5.7.0和mockito 3.5.10.

I am using Surefire 3.0.0-M5, junit 5.7.0 and mockito 3.5.10.

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-junit-jupiter</artifactId>
            <scope>test</scope>
        </dependency>

不用说,在使用JPMS进行模块化之前,这种方法在行家中效果很好.

Needless to say this worked well in maven before switching to modularising with JPMS.

我已阅读,并尝试使用junit-platform-maven-plugin替代surefire,但在模仿中遇到了类似的问题.

I have read Testing in the modular world and tried the junit-platform-maven-plugin as a replacement for surefire but ran into similar problems with mockito.

我们将不胜感激.

推荐答案

TL; DR —您需要配置Surefire插件以传递

TL;DR — You need to configure the Surefire Plugin to pass the --add-opens option to java when it runs your test…

-添加打开

如果您必须允许类路径上的代码进行深层反思来访问非公共成员,请使用--add-opens运行时选项.

--add-opens

If you have to allow code on the class path to do deep reflection to access nonpublic members, then use the --add-opens runtime option.

某些库进行深层反射,表示setAccessible(true),因此它们可以访问所有成员,包括私有成员.您可以使用java命令行上的--add-opens选项授予此访问权限...

Some libraries do deep reflection, meaning setAccessible(true), so they can access all members, including private ones. You can grant this access using the --add-opens option on the java command line…


尽管我无法按原样重现100%您所提出的错误消息,但我仍然能够产生几乎相同的错误消息.它与您的相似,我相信我和您的根本原因(和解决方案)都是相同的.


Although I wasn't able to reproduce 100% verbatim the error message in your question, I was able to produce one that was pretty much the same. It was similar enough to yours, that I'm confident that the root cause (and the solution) of both mine and yours is the same.

在此演示中,您可以下载并构建 ,我解决了遇到的错误...

In this demo that you can download and build, I resolved the error I got with…

…
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0-M5</version>
    <configuration>
        …
        <argLine>add-opens foo.bar/foo.bar=ALL-UNNAMED</argLine>
        …
    </configuration>
</plugin>
…

下载并构建演示 .随意修改它,但您认为合适.

Download and build the demo. Feel free to modify it however you see fit.

这篇关于使用JPMS的maven中的Mockito无法访问带有修饰符"private"的类成员.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆