模块化JavaFX项目TestFX单元测试报包未导出至org.testfx.junit5错误
模块化JavaFX项目TestFX单元测试权限报错
问题现象
在使用TestFX运行GUI按钮的单元测试时,@Start注解标注的类抛出如下错误:
Unable to make public void com.candle.fileexplorertest.view.DirectoryButtonControllerTests.start(javafx.stage.Stage) accessible: module FileExplorer does not "exports com.candle.fileexplorertest.view" to module org.testfx.junit5.
问题背景
- 主代码的
module-info.java文件位于src/main/java路径下,默认无法访问src/test/java路径下的单元测试包,无法直接将测试代码包导出至org.testfx.junit5模块。 - 曾尝试为测试代码单独创建第二个
module-info.java文件,以此将测试包导出给JUnit5,但该操作引发了其他问题,并未解决报错。 - 该问题仅在模块化JavaFX项目中出现,若删除主路径下的
module-info.java文件,测试即可正常运行。
相关代码
单元测试类代码
注:项目包含其他未展示的关联类,当前问题仅与单元测试代码相关
package com.candle.fileexplorertest.view; (imports here) @ExtendWith(ApplicationExtension.class) public class DirectoryButtonControllerTests { DirectoryButtonController testButton; DirectoryButtonViewModel viewModel; Image image; @Start public void start(Stage stage) { viewModel = mock(DirectoryButtonViewModel.class); image = new Image("/com/candle/fileexplorer/images/16/Folder.png"); testButton = new DirectoryButtonController(viewModel, image); Parent sceneRoot = new StackPane(testButton); Scene scene = new Scene(sceneRoot); stage.setScene(scene); stage.show(); stage.toFront(); } @Test public void goToDirectory_shouldTellViewModel_whenButtonClicked(FxRobot robot) { robot.clickOn(testButton); verify(viewModel).goToDirectory(); } }
主模块module-info.java配置
module FileExplorer { requires javafx.controls; requires javafx.fxml; requires javafx.graphics; exports com.candle.fileexplorer; opens com.candle.fileexplorer to javafx.graphics; opens com.candle.fileexplorer.view to javafx.fxml; }
可行解决方案
无需删除主模块module-info.java切换为非模块化模式,以下两种方案均可解决问题:
- 方案一:测试运行期动态添加模块导出(侵入性最低,推荐)
不需要修改主模块的module-info.java,直接在构建工具的测试任务配置中添加JVM参数,在测试运行阶段将测试包动态导出、开放给TestFX模块即可。
Maven配置示例(修改maven-surefire-plugin插件配置):
Gradle配置示例(修改test任务配置):<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.1.2</version> <configuration> <argLine> --add-exports FileExplorer/com.candle.fileexplorertest.view=org.testfx.junit5 --add-opens FileExplorer/com.candle.fileexplorertest.view=org.testfx.junit5 </argLine> </configuration> </plugin>
该方案所有权限调整仅作用于测试运行阶段,不会污染主模块的正式配置。test { jvmArgs( '--add-exports', 'FileExplorer/com.candle.fileexplorertest.view=org.testfx.junit5', '--add-opens', 'FileExplorer/com.candle.fileexplorertest.view=org.testfx.junit5' ) } - 方案二:正确配置独立测试模块
如果希望通过模块系统原生管理测试依赖,可在src/test/java路径下创建测试专属的module-info.java,注意要将测试模块声明为开放模块,同时补全所有测试相关依赖,避免之前出现的依赖缺失冲突问题,配置示例:
主流构建工具(Maven/Gradle)默认会将测试路径下的模块描述符仅应用于测试编译、运行阶段,不会和主模块配置冲突,之前操作引发其他问题通常是漏写依赖、或者模块声明格式错误导致的。open module FileExplorerTest { requires FileExplorer; requires org.junit.jupiter.api; requires org.testfx.junit5; requires org.mockito; requires javafx.graphics; exports com.candle.fileexplorertest.view; }
内容的提问来源于stack exchange,提问作者cachandlerdev
相关产品推荐
相关产品推荐

