web-dev-qa-db-ja.com

Mavenで実行されたJunitテストでsrc / test / resourcesにアクセスできないのはなぜですか?

次のコードの実行に問題があります。

configService.setMainConfig("src/test/resources/MainConfig.xml");

Junit @Beforeメソッド内から。

これは、Mavenがターゲットフォルダを構築する方法ですか?

45
Michael W

_MainConfig.xml_に直接アクセスします。 _src/test/resources_ディレクトリの内容は、CLASSPATHのルートに配置されます。

より正確に:_src/test/resources_の内容は_target/test-classes_にコピーされるため、次のプロジェクト構造がある場合:

_.
└── src
    └── test
        ├── Java
        │   └── foo
        │       └── C.Java
        └── resources
            ├── a.xml
            └── foo
                └── b.xml
_

次のテストCLASSPATHの内容が生成されます。

  • _/foo/C.class_
  • _/a.xml_
  • _/foo/b.xml_

Java source)からファイルに実際にアクセスするには、getClass().getResource("/MainConfig.xml").getFile()を使用します。

66

setMainConfigは、相対ファイルパスではなく、ClassLoaderを使用してロードするリソースのパスを想定していると思います。この神秘的なconfigService.setMainConfigメソッドのjavadocにリンクすると役立ちます。

推測が正しければ、パスはMainConfig.xmlになります。 Maveはsrc/test/resourcesの内容をtarget/test-classes(IIRC)フォルダーにコピーします。そして、このtest-classesフォルダーは、単体テストのクラスパスにあります。

3
JB Nizet

今日同じ問題にぶつかり、いくつかの解決策を見つけました。

最初に、ここに私のファイル構造があります:

.
└── src
│   └── test
│       ├── Java
│       │   └── mypackage
│       │       └── MyClassTest.Java
│       └── resources
│           └── image.jpg
└── target
    └── test-classes
            ├── image.jpg
            └── mypackage
                └── MyClassTest.class  

機能していないもの:(Java 11 synthax)

var imgFile = new File("image.jpg"); // I was expecting that Junit could find the file.
var absPath = file.getAbsolutePath(); // /home/<user>/../<project-root>/image.jpg
var anyFileUnderThisPath = file.exists(); // false

気付くことができるのは、絶対パスが私の画像上でまったく指していないということです!しかし、プロジェクトルートにイメージがあった場合、それは機能していました。

解決策1:パス(Java 7)で導入

var relPath = Paths.get("src", "test", "resources", "image.jpg"); // src/test/resources/image.jgp
var absPath = relPath.toFile().getAbsolutePath(); // /home/<user>/../<project-root>/src/test/resources/image.jpg
var anyFileUnderThisPath = new File(absPath).exists(); // true

ご覧のとおり、正しいファイルを指し示しています。

ソリューション2:ClassLoader

var classLoader = getClass().getClassLoader();
var url = classLoader.getResource("image.jpg"); // file:/home/<user>/../<project-root>/target/test-classes/image.jpg
var file = new File(url.getFile()); // /home/<user>/../<project-root>/target/test-classes/image.jpg
var anyFileUnderThisPath = file.exists(); // true

ここで、ファイルはターゲットディレクトリの下で検索されることに注意してください!そしてそれは動作します。

解決策3:ファイル(動作しない例の適応)

var absPath = new File("src/test/resources/image.jpg").getAbsolutePath();
var var anyFileUnderThisPath = new File(absPath).exists(); // true

絶対パスを取り、src/test/resources/プレフィックスとして。

概要

3つのソリューションはすべて動作しますが、src/test/resources/は、私自身の意見ではエレガントではないため、2番目のソリューション(ClassLoader)を好む理由です。

ソース:

2
KeyMaker00