it-swarm.com.de

Wie bekomme ich den Pfad des Verzeichnisses src/test/resources in JUnit?

Ich weiß, dass ich eine Datei von src/test/resources laden kann mit:

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

Aber wie bekomme ich den vollständigen Pfad zum Verzeichnis src/test/resources directory ? Ich möchte keine Datei laden. Ich möchte nur den Pfad des Verzeichnisses kennen.

194
Rory

Versuchen Sie mit der ClassLoader-Klasse zu arbeiten: 

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

Eine ClassLoader ist für das Laden in Klassen verantwortlich. Jede Klasse hat einen Verweis auf eine ClassLoader. Dieser Code gibt eine File aus dem Ressourcenverzeichnis zurück. Beim Aufruf von getAbsolutePath() wird die absolute Path zurückgegeben.

Javadoc für ClassLoader: http://docs.Oracle.com/javase/7/docs/api/Java/lang/ClassLoader.html

152
ashosborne1

Sie müssen sich nicht mit Klassenladern herumschlagen. Tatsächlich ist es eine schlechte Angewohnheit, sich anzuschließen, weil Klassenlade-Ressourcen nicht Java.io.File-Objekte sind, wenn sie sich in einem JAR-Archiv befinden.

Maven legt automatisch das aktuelle Arbeitsverzeichnis fest, bevor Tests ausgeführt werden. Sie können also einfach Folgendes verwenden:

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

resourcesDirectory.getAbsolutePath() liefert den korrekten Wert, wenn Sie das wirklich brauchen.

Ich empfehle, ein src/test/data-Verzeichnis anzulegen, wenn Ihre Tests über das Dateisystem auf Daten zugreifen sollen. Dies macht deutlich, was Sie tun.

224
Steve C

Ich würde einfach Path von Java 7 verwenden

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

Ordentlich und sauber!

48
JeanValjean

Wenn es sich um ein Frühjahrsprojekt handelt, können wir den folgenden Code verwenden, um Dateien aus dem Ordner src/test/resource abzurufen.

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

Ich habe ein Maven3-Projekt mit JUnit 4.12 und Java8 . Um den Pfad einer Datei mit dem Namen myxml.xml unter src/test/resources zu erhalten, mache ich dies aus dem Testfall heraus

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

Getestet auf Ubuntu 14.04 mit IntelliJ IDE . Referenz hier .

7
Antony

Es gibt Unterschiede und Einschränkungen bei den Optionen von @Steve C und @ ashosborne1. Sie müssen angegeben werden, glaube ich. 

Wann können wir verwenden: File resourcesDirectory = new File("src/test/resources");?

  • 1 Wenn Tests nur über Maven und nicht über IDE ausgeführt werden.
  • 2.1 Wenn Tests über Maven oder durchgeführt werden sollen
  • 2.2 über IDE und nur ein Projekt wird in die IDE importiert. (Ich verwende den Begriff „importiert“, da er in IntelliJ IDEA verwendet wird. Ich denke, Benutzer von Eclipse importieren auch ihr Maven-Projekt). Dies funktioniert, da das Arbeitsverzeichnis beim Ausführen von Tests über IDE mit Ihrem Projekt identisch ist.
  • 3.1 Wenn Tests über Maven oder durchgeführt werden sollen 
  • 3.2 über IDE und mehrere Projekte werden in IDE importiert (wenn Sie kein Student sind, importieren Sie normalerweise mehrere Projekte),UND, bevor Sie Tests über IDE ausführen, konfigurieren Sie das Arbeiten manuell Verzeichnis für Ihre Tests. Dieses Arbeitsverzeichnis sollte auf Ihr importiertes Projekt verweisen, das die Tests enthält. Standardmäßig ist das Arbeitsverzeichnis aller in IDE importierten Projekte nur eines. Wahrscheinlich ist dies nur eine Einschränkung von IntelliJ IDEA, aber ich denke, dass alle IDEs so funktionieren. Und diese Konfiguration, die manuell vorgenommen werden muss, ist überhaupt nicht gut. Wenn Sie mit mehreren Tests arbeiten, die in verschiedenen Maven-Projekten vorhanden sind, aber in ein großes "IDE" -Projekt importiert wurden, zwingen wir uns, dies zu merken und dürfen sich nicht entspannen und Ihre Arbeit genießen.

Die von @ ashosborne1 angebotene Lösung (persönlich bevorzuge ich diese) erfordert zwei zusätzliche Anforderungen, die vor dem Ausführen von Tests ausgeführt werden müssen. Hier finden Sie eine Liste mit Schritten zur Verwendung dieser Lösung:

  • Erstellen Sie einen Testordner ("teva") und eine Datei ("Readme") in "src/test/resources /":

    src/test/resources/teva/readme

    Die Datei muss im Testordner erstellt werden, andernfalls funktioniert sie nicht. Maven ignoriert leere Ordner.

  • Mindestens einmal Projekt über mvn clean install erstellen. Es werden auch Tests ausgeführt. Es kann ausreichend sein, nur Ihre Testklasse/Methode über maven auszuführen, ohne ein gesamtes Projekt zu erstellen. Als Ergebnis werden Ihre Testressourcen in Testklassen kopiert. Hier ist ein Pfad: target/test-classes/teva/readme
  • Danach können Sie auf den Ordner mit dem Code zugreifen, der bereits von @ ashosborne1 angeboten wird (es tut mir leid, dass ich diesen Code in dieser Liste nicht korrekt bearbeiten konnte):
public static final String TEVA_FOLDER = "teva"; ... 
URL tevaUrl = YourTest.class.getClassLoader().getResource(TEVA_FOLDER); 
String tevaTestFolder = new File(tevaUrl.toURI()).getAbsolutePath();

Jetzt können Sie Ihren Test über IDE beliebig oft ausführen. Bis Sie mvn clean ausführen. Der Zielordner wird gelöscht.

Das Erstellen einer Datei in einem Testordner und das erstmalige Ausführen von maven vor dem Ausführen von Tests über IDE sind erforderliche Schritte. Ohne diese Schritte erhalten Sie einen Fehler, wenn Sie nur in Ihrer IDE Testressourcen erstellen und dann test schreiben und nur über IDE ausführen. Durch Ausführen von Tests über mvn werden Testressourcen in target/test-classes/teva/readme kopiert, und sie werden für einen Classloader verfügbar.

Sie fragen sich vielleicht, warum ich mehr als ein Maven-Projekt in IDE importieren muss und warum so viele komplizierte Dinge? Für mich eine der Hauptmotivation: IDA-bezogene Dateien vom Code fernzuhalten. Ich erstelle ein neues Projekt in meiner IDE. Es handelt sich hierbei um ein gefälschtes Projekt, das nur IDE-Dateien enthält. Dann importiere ich bereits vorhandene Maven-Projekte. Ich erzwinge, dass diese importierten Projekte IDEA -Dateien nur in meinem ursprünglichen gefälschten Projekt behalten. Daher sehe ich keine IDE-bezogenen Dateien im Code. SVN sollte sie nicht sehen (bitte bieten Sie nicht an, svn/git zu konfigurieren, um solche Dateien zu ignorieren, bitte). Es ist auch sehr bequem.

6
Alexandr

Die einfachste und sauberste Lösung, die ich verwende, nehme an, der Name der Testklasse lautet TestQuery1 und es gibt ein resources-Verzeichnis in Ihrem test-Ordner:

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

Um den URI von TestQuery1 zu erhalten, machen Sie:

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

Um die URI einer der Dateien TestQuery1 abzurufen, führen Sie folgende Schritte aus:

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

Der gesamte Inhalt in src/test/resources wird in den target/test-classes-Ordner kopiert. Um eine Datei aus Testressourcen während des Maven-Builds zu erhalten, müssen Sie sie aus dem test-classes-Ordner laden.

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

Nervenzusammenbruch:

  1. getClass().getProtectionDomain().getCodeSource().getLocation().toURI() - Geben Sie die URI für target/test-classes an.
  2. resolve(Paths.get("somefile")) - löst someFile im target/test-classes-Ordner auf.

Ursprüngliche Antwort wird von this übernommen.

3
Cherry

Sie können eine Datei nicht aus einem Ressourcenordner für Tests in einem allgemeinen Fall verwenden. Der Grund ist, dass Ressourcendateien im Ressourcenordner in einem Glas gespeichert werden. Sie haben also keinen richtigen Pfad im Dateisystem.

Die einfachste Lösung kann sein:

  1. Kopieren Sie eine Datei aus den Ressourcen in den temporären Ordner und rufen Sie den Pfad zu dieser temporären Datei ab.
  2. Führen Sie Tests mit einem temporären Pfad durch.
  3. Löschen Sie die temporäre Datei.

Mit TemporaryFolder aus JUnit können temporäre Dateien erstellt und nach Abschluss des Tests gelöscht werden. Klassen aus der Bibliothek guava werden zum Kopieren eines Ressourcenordners für Dateiformate verwendet. 

Wenn Sie einen Unterordner im Ressourcenordner wie good verwenden, müssen Sie dem Ressourcenpfad nicht den führenden / hinzufügen.

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

Verwenden Sie das folgende Verfahren, um den Winterschlaf mit Feder in Ihre Unit-Tests einzuspritzen:

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

Wenn der hibernate.cfg.xml-Ordner nicht in Ihrem src/test/resources-Ordner vorhanden ist, wird er automatisch auf den Ordner src/main/resources zurückgesetzt.

0
whitebrow

Verwenden Sie .getAbsolutePath () für Ihr File-Objekt.

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