当前位置: 首页 > 知识库问答 >
问题:

maven中使用JPMS的Mockito不能访问带有修饰符“private”的类的成员

袁亦
2023-03-14

我正在将一个代码库迁移到Java11和JPMS/Jigsaw上,但在嘲讽方面遇到了一些麻烦。

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));
    }
}
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"
        <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>

我读过模块化世界中的测试,并尝试使用junit-platform-maven-plugin作为surefire的替代,但在Mockito中遇到了类似的问题。

我们将不胜感激。

共有1个答案

丌官远
2023-03-14

tl;dr-您需要配置Surefire插件,以便在运行您的测试时将--add-opens选项传递给java

如果必须允许类路径上的代码进行深度反射访问非公共成员,则使用--add-opens运行时选项。

有些库做深度反射,意思是setAccessible(true),因此它们可以访问所有成员,包括私有成员。您可以使用java命令行上的--add-opens选项授予此访问权限…

在这个演示,你可以下载和构建,我解决了错误,我得到了…

…
<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>
…

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

 类似资料:
  • 最近,我正在编写一个类,我决定将其作为包私有(即没有访问修饰符,或默认的)。它有一个内部类和一些帮助器方法,还有一个方法打算由同一个包中的类使用。所有这些类成员都是。但是后来我有了一个想法:这个方法应该有访问修饰符还是没有访问修饰符,就像包含它的类一样? 一方面,由于类本身是package-private的,只能在其包内访问和使用,因此没有实际的理由将方法设为。但同时,从语义上讲,这个方法意在成为

  • 我想如果一个类被声明为public,它可以从任何地方访问。但是为什么eclipse称之为错误呢?

  • 本文向大家介绍简述private、protected、pubic、internal修饰符的访问权限相关面试题,主要包含被问及简述private、protected、pubic、internal修饰符的访问权限时的应答技巧和注意事项,需要的朋友参考一下 答: private : 私有成员, 在类的内部才可以访问(只能从其声明上下文中进行访问) protected : 保护成员,该类内部和从该类派生的

  • C++ 类 & 对象 数据封装是面向对象编程的一个重要特点,它防止函数直接访问类类型的内部成员。类成员的访问限制是通过在类主体内部对各个区域标记 public、private、protected 来指定的。关键字 public、private、protected 称为访问修饰符。 一个类可以有多个 public、protected 或 private 标记区域。每个标记区域在下一个标记区域开始之前

  • JAVA访问修饰符的可访问性 公众 在 同一班级 同一套餐 子类 宇宙/其他软件包 我在互联网上寻找这些问题的答案,因为我有多个答案。一个视频说未声明的访问修饰符是公共的,而我看到另一个书面来源说未声明的访问修饰符在子类和其他包中没有限制。试图确认哪个是真的。

  • 问题内容: 我在Java中有一个“私有静态”嵌套类。访问修饰符对此类中的字段和方法的意义是什么?我已经尝试了公共和私有方式,但对我的申请没有影响。 问题答案: 两种嵌套类:1.静态(嵌套类)和2.非静态(也称为内部类) 现在,外部类可以访问内部类的所有成员,但是当您想要限制某些外部类访问它时,实际上您可以对类(嵌套类)的成员使用访问说明符。 有趣的读物:Source1,Source2