首页 > 解决方案 > 未添加到类路径的测试资源

问题描述

使用 Maven 构建项目时未将测试资源添加到类路径

项目结构:

project/pom.xml
   /dist/pom.xml
        /src/main/resources/db/test.sql
   
   /test/pom.xml
        /src/test/com/loader/TestLoader.java

这是 dist 模块的 pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>test1</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>dist</artifactId>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>test-jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>1.12</version>
                <executions>
                    <execution>
                        <id>add-test-resource</id>
                        <phase>generate-test-sources</phase>
                        <goals>
                            <goal>add-test-resource</goal>
                        </goals>
                        <configuration>
                            <resources>
                                <resource>
                                    <directory>src/main/resources</directory>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

这是测试模块的 pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>test1</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>test</artifactId>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <artifactId>dist</artifactId>
            <groupId>org.example</groupId>
            <version>1.0-SNAPSHOT</version>
            <type>test-jar</type>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

以及尝试从 dist 的模块中读取 test.sql 的 JUnit 测试

@RunWith(JUnit4.class)
public class TestLoader {

    @Test
    public void test() throws Exception {
        Path path = Paths.get(ClassLoader.getSystemResource("db/test.sql").toURI());

        System.out.println(path.toFile().exists());
    }

当我从 IDEA 运行此测试时,一切正常,但是当我尝试使用 command 时mvn clean install,我收到找不到资源的错误。

可能是什么错误?

标签: javamaven

解决方案


文件检测

ClassLoader.getSystemResource()将根据测试类的执行方式返回不同类型的 URL:

  • 从 IDE 中,它是一个文件(“file:/path/to/db/test.sql”),所以Path.get(uri)可以
  • 来自 Maven,它是一个 JAR (ZIP) 条目(“jar:file:/path/to/dist-1.0-SNAPSHOT.jar!/db/test.sql”),所以Path.get(uri)抛出一个FileSystemNotFoundException

URL 足以知道条目是否存在。
如果是这样,则可以使用 读取其内容url.openStream()

URL url = ClassLoader.getSystemResource("db/test.sql");
if (url == null) {
    // File not found
} else {
    try (InputStream is = url.openStream()) {
        (...)
    }
}

Maven配置

根据dist模块的目标,可以有 2 种配置。

1-dist是 API 的一部分,将在test

然后根本不需要使用test-jar执行目标。

  • dist/pom.xmlbuild:可以删除整个部分
  • test/pom.xml: 还好
2-dist仅用于测试(在test模块和其他模块中)

然后,将dist资源放在测试目录中更加一致。

  • db/test.sql应该移到dist/src/test/resources
  • dist/pom.xml:该test-jar部分仍然存在,但build-helper-maven-plugin变得无用并且可以删除
  • test/pom.xml:要使其工作,依赖项classifier是强制性的
<dependency>
    <groupId>${project.groupId}</groupId>
    <artifactId>dist</artifactId>
    <version>${project.version}</version>
    <scope>test</scope>
    <classifier>tests</classifier>
</dependency>

推荐阅读