web-dev-qa-db-ja.com

JUnitでsrc/test/resourcesディレクトリのパスを取得する方法

私はsrc/test/resourcesからファイルをロードできることを知っています:

getClass().getResource("somefile").getFile()

しかし、どのようにしてsrc/test/resources ディレクトリ へのフルパスを取得することができますか。

209
Rory

ClassLoaderクラスを使ってみてください。

ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("somefile").getFile());
System.out.println(file.getAbsolutePath());

ClassLoaderはクラスへのロードを担当します。すべてのクラスはClassLoaderへの参照を持ちます。このコードは、リソースディレクトリからFileを返します。その上でgetAbsolutePath()を呼び出すと、その絶対的なPathが返されます。

ClassLoaderのJavadoc: http://docs.Oracle.com/javase/7/docs/api/Java/lang/ClassLoader.html

163
ashosborne1

クラスローダーをいじる必要はありません。実際、クラスローダーリソースはjarアーカイブ内にあるときはnot Java.io.Fileオブジェクトなので、侵入するのは悪い習慣です。

Mavenはテストを実行する前に自動的に現在の作業ディレクトリを設定します。

    File resourcesDirectory = new File("src/test/resources");

それがあなたが本当に必要なものであるならば、resourcesDirectory.getAbsolutePath()は正しい値を返します。

テストでファイルシステムを介してデータにアクセスする場合は、src/test/dataディレクトリを作成することをお勧めします。これにより、自分がしていることが明確になります。

237
Steve C

私は単にJava 7から Path を使います

Path resourceDirectory = Paths.get("src","test","resources");

清楚な!

53
JeanValjean

春のプロジェクトの場合は、 src/test/resource フォルダーからファイルを取得するために以下のコードを使用できます。

File file = ResourceUtils.getFile(this.getClass().getResource("/some_file.txt"));
20

JUnit 4.12とJava 8を使ったMaven 3プロジェクトがあります。 myxml.xmlの下にあるsrc/test/resourcesというファイルのパスを取得するために、テストケース内からこれを行います。

@Test
public void testApp()
{
    File inputXmlFile = new File(this.getClass().getResource("/myxml.xml").getFile());
    System.out.println(inputXmlFile.getAbsolutePath());
    ...
}

IntelliJ IDEを使ってUbuntu 14.04でテストしました。参照 ここ .

9
Antony

@Steve Cと@ ashosborne1が提供するオプションには違いと制約があります。それらは指定されなければなりません、と私は思います。

いつFile resourcesDirectory = new File("src/test/resources");を使うことができますか?

  • 1テストがmavenのみを介して実行され、IDEを介して実行されない場合。
  • 2.1テストがmavenまたはを介して実行される予定の場合
  • 2.2 _ IDEを介してIDEにインポートされるプロジェクトは1つだけです。 (私は「インポート」という用語を使用していますが、IntelliJ IDEAで使用されているためです。Eclipseのユーザーも自分のMavenプロジェクトをインポートしていると思います)。これはうまくいくでしょう、IDEでテストを実行したときの作業ディレクトリはあなたのプロジェクトと同じです。
  • 3.1テストがMavenまたはを介して実行される予定の場合
  • IDEを介して3.2、および複数のプロジェクトがIDEにインポートされます(あなたが学生でない場合は、通常複数のプロジェクトをインポートします)、 _および_ IDEを介してテストを実行する前に、手動でテスト用の作業ディレクトリを設定します。その作業ディレクトリは、テストを含むインポート済みプロジェクトを参照する必要があります。デフォルトでは、IDEにインポートされたすべてのプロジェクトの作業ディレクトリは1つだけです。おそらくそれはIntelliJ IDEAだけの制限ですが、私はすべてのIDEがこのように動作すると思います。そして手動で行わなければならないこの設定は全く良くありません。 1つの大きな「IDE」プロジェクトにインポートされた、さまざまなMavenプロジェクトに存在するいくつかのテストを操作することで、これを覚えていることを強いられ、リラックスして仕事から喜びを得ることはできません。

@ ashosborne1が提供するソリューション(個人的には私がこれを好む)は、テストを実行する前に行わなければならない2つの追加要件を必要とします。このソリューションを使用するためのステップのリストはここにあります:

  • 「src/test/resources /」の中にテストフォルダー(「teva」)とファイル(「readme」)を作成します。

    src/test/resources/teva/readme

    ファイルはテストフォルダに作成する必要があります。それ以外の場合は機能しません。 Mavenは空のフォルダを無視します。

  • 少なくとも一度はmvn clean installでプロジェクトをビルドしてください。テストも実行されます。プロジェクト全体を構築せずに、Mavenを介してテストクラス/メソッドだけを実行すれば十分かもしれません。その結果、あなたのテストリソースはテストクラスにコピーされます、これがパスです:target/test-classes/teva/readme
  • その後、@ ashosborne1によって既に提供されているコードを使用してフォルダにアクセスできます(申し訳ありませんが、このアイテムリスト内でこのコードを正しく編集できませんでした)。
public static final String TEVA_FOLDER = "teva"; ... 
URL tevaUrl = YourTest.class.getClassLoader().getResource(TEVA_FOLDER); 
String tevaTestFolder = new File(tevaUrl.toURI()).getAbsolutePath();

これでIDEを使って何度でもテストを実行できます。あなたがmvn cleanを走らせるまで。ターゲットフォルダをドロップします。

IDEでテストを実行する前に、テストフォルダ内にファイルを作成し、最初にmavenを実行することが必要な手順です。これらの手順がないと、IDEテストリソースを作成してからtestを書いてIDEのみで実行すると、エラーが発生します。 mvnでテストを実行すると、テストリソースがtarget/test-classes/teva/readmeにコピーされ、それらはクラスローダーからアクセス可能になります。

あなたは尋ねるかもしれません、なぜ私はIDEに複数のMavenプロジェクトをインポートする必要があるのですか、そしてなぜそれほど多くの複雑なことをするのですか?私にとって、主な動機の1つは、IDA関連のファイルをコードから遠ざけることです。まずIDEで新しいプロジェクトを作成します。それは偽のプロジェクトです、それはちょうどIDE関連のファイルの保有者です。次に、既存のMavenプロジェクトをインポートします。私はこれらのインポートされたプロジェクトにIDEAファイルを私の元の偽のプロジェクトだけに保存​​させます。結果として、私はコードの中にIDE関連のファイルを見ません。 SVNはそれらを見るべきではありません(そのようなファイルを無視するようにsvn/gitを設定することを申し出ないでください)。まさにとても便利です。

7
Alexandr

src/test/resources内のすべてのコンテンツはtarget/test-classesフォルダーにコピーされます。そのため、Mavenのビルド中にテストリソースからファイルを取得するには、次のようにtest-classesフォルダからロードする必要があります。

Paths.get(
    getClass().getProtectionDomain().getCodeSource().getLocation().toURI()
).resolve(
    Paths.get("somefile")
).toFile()

壊す:

  1. getClass().getProtectionDomain().getCodeSource().getLocation().toURI() - target/test-classesへのURIを教えてください。
  2. resolve(Paths.get("somefile")) - someFiletarget/test-classesフォルダーに解決します。

元のanwserは これ から取られます

7
Cherry

私が使用する最も簡単でわかりやすい解決策は、テストクラスの名前がTestQuery1で、resourcesフォルダに次のようにtestディレクトリがあるとします。

├── Java
│   └── TestQuery1.Java
└── resources
    └── TestQuery1
        ├── query.json
        └── query.rq

TestQuery1のURIを取得するには:

URL currentTestResourceFolder = getClass().getResource("/"+getClass().getSimpleName());

ファイルTestQuery1のいずれかのURIを取得するには、次のようにします。

File exampleDir = new File(currentTestResourceFolder.toURI());
URI queryJSONFileURI = exampleDir.toURI().resolve("query.json");
5
Noor

一般的なケースでは、テスト用のリソースフォルダーからファイルを使用することはできません。その理由は、リソースフォルダ内のリソースファイルがjarファイル内に格納されているためです。そのため、ファイルシステムに実際のパスはありません。

最も簡単な解決策は次のとおりです。

  1. ファイルをリソースから一時フォルダにコピーし、その一時ファイルへのパスを取得します。
  2. 一時パスを使用してテストを行います。
  3. 一時ファイルを削除してください。

TemporaryFolderからのJUnitは、一時ファイルを作成し、テストが終了した後でそれを削除するために使用できます。 guavaライブラリからのクラスは、ファイルフォームリソースフォルダをコピーするために使用されます。

goodのようにresourcesフォルダーでサブフォルダーを使用する場合は、先頭の/をリ​​ソースパスに追加する必要はありません。

public class SomeTest {

    @Rule
    public TemporaryFolder tmpFolder = new TemporaryFolder();


    @Test
    public void doSomethinge() throws IOException {
        File file = createTmpFileFromResource(tmpFolder, "file.txt");
        File goodFile = createTmpFileFromResource(tmpFolder, "good/file.txt");

        // do testing here
    }

    private static File createTmpFileFromResource(TemporaryFolder folder,
                                                  String classLoaderResource) throws IOException {
        URL resource = Resources.getResource(classLoaderResource);

        File tmpFile = folder.newFile();
        Resources.asByteSource(resource).copyTo(Files.asByteSink(tmpFile));
        return tmpFile;
    }

}
0
v.ladynev

ユニットテストでHibernate with Springをインジェクションするには、以下を使用してください。

@Bean
public LocalSessionFactoryBean getLocalSessionFactoryBean() {
    LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
    localSessionFactoryBean.setConfigLocation(new ClassPathResource("hibernate.cfg.xml"));
    localSessionFactoryBean.setPackagesToScan("com.example.yourpackage.model");
    return localSessionFactoryBean;
}

hibernate.cfg.xmlフォルダーにsrc/test/resourcesが存在しない場合は、自動的にsrc/main/resourcesフォルダー内のものにフォールバックします。

0
whitebrow

Fileオブジェクトに.getAbsolutePath()を使用してください。

getClass().getResource("somefile").getFile().getAbsolutePath()
0
GreatDantone