You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何配置Surefire插件,在Maven项目中运行非公开测试类?

解决Java模块项目中非public测试类/方法的Surefire执行问题

这个问题本质是**Java模块系统(JPMS)**和早期版本的Surefire插件兼容性不足导致的——旧版本的Surefire在处理模块内非public测试类时,无法正确通过反射访问,触发了InaccessibleObjectException。下面是几个靠谱的解决方案,按推荐度排序:

方案1:升级Surefire插件和JUnit Jupiter版本(最推荐)

早期的maven-surefire-plugin:3.0.0-M5对JPMS的支持还不够完善,后续版本已经修复了非public测试的访问问题。建议直接升级到稳定兼容的版本组合:

示例POM配置

<!-- 构建插件部分 -->
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <!-- 推荐使用3.1.0+的稳定版 -->
            <version>3.1.2</version>
        </plugin>
    </plugins>
</build>

<!-- 依赖部分 -->
<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <!-- 与Surefire 3.1.x兼容的JUnit版本,推荐5.9.x+ -->
        <version>5.9.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

升级后,Surefire会自动处理JPMS模块内的非public测试类/方法,无需修改测试代码或模块配置,直接执行mvn test即可正常运行。

方案2:调整模块描述符开放测试包

如果暂时无法升级版本,可以修改module-info.java,将测试所在的包开放给JUnit和Surefire相关模块,允许它们通过反射访问非public类:

示例module-info.java配置

// 方式1:开放整个模块给所有测试相关模块(简单但权限稍大)
open module sample.core {
    requires org.junit.jupiter.api;
}

// 方式2:精准开放指定包给特定模块(更安全)
module sample.core {
    requires org.junit.jupiter.api;
    // 开放测试包给JUnit平台、JUnit引擎和Surefire的JUnit平台适配器
    opens org.sample to org.junit.platform.commons, org.junit.jupiter.engine, org.apache.maven.surefire.junitplatform;
}

这种方式需要手动维护模块权限,后续如果更换测试框架或插件版本,可能需要调整开放的模块列表。

方案3:临时关闭模块系统(不推荐)

如果是单模块项目且对JPMS特性依赖不高,可以通过Maven编译插件参数临时关闭模块系统,让测试运行在传统的类路径模式下:

示例POM配置

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.11.0</version>
    <configuration>
        <compilerArgs>
            <!-- 关闭模块系统,使用类路径模式 -->
            <arg>--no-module-directories</arg>
        </compilerArgs>
    </configuration>
</plugin>

⚠️ 注意:这个方案会丢失JPMS的模块隔离优势,仅适合临时应急场景。


内容的提问来源于stack exchange,提问作者diziaq

火山引擎 最新活动