【问题标题】:Unit test with resources loaded with ClassLoader and Maven Surefire使用 ClassLoader 和 Maven Surefire 加载资源的单元测试
【发布时间】:2026-02-04 04:30:01
【问题描述】:

我有一个 JavaFX 项目,它使用 getClassLoader().getResource 加载 FXML 文件,例如:

Main.class.getClassLoader().getResource("fxml/App.fxml"). 

主代码运行良好,但是当我使用 Maven Surefire 插件运行测试时出现此错误:

java.lang.IllegalStateException: Location is not set.
javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2459)
javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)

经过进一步调查,我发现在执行测试时调用 getClassLoader().getResource() 时,它尝试解析的路径位于“target/test-classes”文件夹中,而资源位于“target/classes”中“ 文件夹。我该如何解决这个问题? 如果相关,我的项目遵循 Maven 的默认结构。

编辑:添加执行资源加载的代码行

【问题讨论】:

    标签: java maven testing classloader maven-surefire-plugin


    【解决方案1】:

    在 Maven 中运行测试时,类路径由 target/classestarget/test-classes 组成

    target/classes用于存放编译后的类和资源(src/main/java下,src/main/resources下) target/test-classes用于存放编译后的测试类和测试资源(分别在src/test/java和src/test/resources下)

    你没有显示做getClassLoader().getResource()的代码,最重要的是这个getResource的参数 - 它是如何在运行时(测试期间)得到解决的,所以很难说更多,但可能是问题就是这个参数没有指定正确。

    例如,如果它的文件src/main/resources/sample.xml 应该被解析为:

    getClassLoader().getResource("/sample.xml")
    

    【讨论】:

    • 不。它应该是 sample.xml,而不是 /sample.xml。 /sample.xml 是当您使用 SomeClass.getResource() 时。
    • 代码为 Main.class.getClassLoader().getResource("fxml/App.fxml")。当我在 IDE 和胖 JAR 中运行该应用程序时,它本身就可以工作。