Was ist der richtige Weg, um während Unit-Tests mit Maven in temporäre Dateien zu schreiben?

Lesezeit: 7 Minuten

Benutzer-Avatar
Brett Ryan

Ich habe einen Komponententest geschrieben, der eine Datei in das Dateisystem schreibt, ohne dass ein Pfad in das Arbeitsverzeichnis geschrieben wird. Wenn es also aus dem Projektverzeichnis ausgeführt wird, schreibt es in das Projektstammverzeichnis, wenn es sich im übergeordneten Projektverzeichnis befindet, schreibt es in das übergeordnete Stammverzeichnis.

Was ist also der richtige Weg, um in das Zielverzeichnis zu schreiben? Möglicherweise ein Verzeichnis innerhalb des Zielverzeichnisses?

Wenn ich ganz einfach angeben target/ Mit der Datei wird in das Ziel des übergeordneten Projekts geschrieben, anstatt in das Ziel des Projekts.

AKTUALISIEREN: Ich möchte die Datei tatsächlich nach Abschluss des Tests. Die Datei ist für ein Extraktionsformat für Drittanbieter, das an die Drittanbieter gesendet werden muss. Der Test kann ein-/ausgeschaltet werden, damit ich ihn nur ausführen kann, wenn sich das Format der Datei zur erneuten Genehmigung ändert. Es ist kein großes Problem, wohin die Datei geht, aber ich hätte gerne etwas, das leicht zu finden ist.

Benutzer-Avatar
Mama

Sie könnten versuchen, zu verwenden Temporärer Ordner JUnit @Rule wie beschrieben hier

Das Temporärer Ordner erstellt einen Ordner im Standardverzeichnis für temporäre Dateien, das durch die Systemeigenschaft java.io.tmpdir angegeben ist. Die Methode newFile erstellt eine neue Datei im temporären Verzeichnis und newFolder erstellt einen neuen Ordner.

Wenn die Testmethode beendet ist, löscht JUnit automatisch alle Dateien und Verzeichnisse in und einschließlich des TemporaryFolder. JUnit garantiert, dass die Ressourcen gelöscht werden, unabhängig davon, ob der Test bestanden wird oder fehlschlägt.


Nach Frage aktualisiert

Sie können das von verwendete Arbeitsverzeichnis ändern maven-surefire-plugin.

<plugins>
    [...]
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.12.3</version>
        <configuration>
          <workingDirectory>${project.build.directory}</workingDirectory>
        </configuration>
      </plugin>
    [...]
</plugins>

Sie können dieses Arbeitsverzeichnis in alles ändern, was Sie für Ihre Tests benötigen, z ${project.build.directory}/my_special_dir/.

Das Arbeitsverzeichnis im Surefire-Plugin wirkt sich nur auf Tests aus, die ausgeführt werden, und NUR auf Tests, die von Maven durchgeführt werden. Wenn Sie Ihre Tests innerhalb einer IDE ausführen, ist das Arbeitsverzeichnis etwas anderes.

  • Danke maba, das ist ein ähnliches Problem wie Bohemian, die Datei landet an einem obskuren Ort. Ich möchte die Datei tatsächlich nach Abschluss des Tests.

    – Brett Ryan

    13. September 2012 um 6:38 Uhr

  • @BrettRyan OK, aktualisiert mit der Änderung des Arbeitsverzeichnisses für das todsichere Plugin. Das sollte reichen.

    – Mama

    13. September 2012 um 6:50 Uhr

  • Fantastisch, danke maba, das ist perfekt und wird auf allen Maschinen, auf denen der Test ausgeführt wird, immer konsistent sein.

    – Brett Ryan

    13. September 2012 um 8:22 Uhr

  • Vielen Dank, dass Sie die ursprüngliche Antwort hinterlassen haben. Das habe ich gebraucht.

    – Yellavon

    17. April 2014 um 16:40 Uhr

  • JUNIT garantiert kein automatisches Löschen, Sie müssen es tun @Rule public TemporaryFolder folder = TemporaryFolder.builder().assureDeletion().build();

    – Vimal-Krishna

    11. Januar 2017 um 15:05 Uhr

Benutzer-Avatar
Bohemien

Man muss das Rad nicht neu erfinden…

Das JDK bietet eine Möglichkeit, eine temporäre Datei zu erstellen und sie beim Beenden automatisch zu löschen:

File file = File.createTempFile( "some-prefix", "some-ext");
file.deleteOnExit();

Verwenden Sie die Datei und sie wird automatisch gelöscht, wenn Ihr Test beendet ist. Das ist alles dazu.

Verwenden Sie die überladene Methode, um das Verzeichnis anzugeben, das für temporäre Dateien verwendet werden soll:

File file = File.createTempFile( "prefix", "ext", new File("/some/dir/path"));

  • Danke Bohemian, ich möchte eigentlich, dass die Datei nach dem Beenden erhalten bleibt, damit ich sie an den Anbieter weiterleiten kann. Ich nehme an, das temporäre Verzeichnis des Systems ist in Ordnung, obwohl ich gehofft hatte, es im Zielverzeichnis zu haben.

    – Brett Ryan

    13. September 2012 um 6:32 Uhr

  • Ich habe das gerade versucht und es stellt sich heraus, dass sich die Datei an einem so obskuren Ort befindet, dass es nicht ratsam wäre, sie zu verwenden. Endete in /var/folders/xf/scvh7yr11m1glr4b663n1hcsnv5lf0/T/test2614442099335581603.xml

    – Brett Ryan

    13. September 2012 um 6:35 Uhr

  • @BrettRyan Kein Problem – Sie können das Verzeichnis angeben, das für temporäre Dateien verwendet wird – siehe bearbeitete Antwort

    – Böhmisch

    13. September 2012 um 7:13 Uhr

  • Danke Bohemian, ich sehe einen Vorteil darin, das temporäre Verzeichnis festlegen zu können, obwohl ich die Möglichkeit mag, dies an einem zuverlässigen Ort unter dem Zielverzeichnis zu haben, anstatt einen bestimmten Ort auf dem Computer zu benötigen.

    – Brett Ryan

    13. September 2012 um 8:24 Uhr

Benutzer-Avatar
CloudyMarble

Ich würde eine Routine schreiben, die bestimmt, wohin die Datei geschrieben werden soll, die ich danach vereinige, im Allgemeinen versuche ich (möglichst) den Zugriff auf persistente Daten in Unittests zu vermeiden, wie Datei-IO oder Datenbankzugriff, dies hat Performance-Gründe und andere auch .

Sehen Sie sich diese Antwort an: https://stackoverflow.com/a/8032504/395659

  • Danke OD, so etwas musste ich bis jetzt noch nie machen. Ich habe den Test geschrieben, um eine Datei zu schreiben, die im Produktionscode an andere Anbieter gesendet wird. Mein Test schreibt die Datei auf die Festplatte, damit ich sie an die Anbieter senden kann, um die Genehmigung zu erhalten. Nach der Genehmigung wird der Test nicht mehr benötigt, kann aber später nützlich sein, wenn sich etwas ändert und die Ausgabe “erneut genehmigt” werden muss.

    – Brett Ryan

    13. September 2012 um 6:19 Uhr

  • aber warum verwenden Sie zu diesem Zweck einen “Einheitentest”? Ich denke, sogar eine separate Klasse mit main () -Methode für diesen Zweck zu haben, ist noch angemessener, als den Unit-Test zu missbrauchen

    – Adrian Schum

    13. September 2012 um 6:42 Uhr

Sie möchten Ihre Tests sowohl von einer IDE als auch von Maven ausführen können, daher ist es am besten, Ihre Tests so zu schreiben, dass sie nicht davon ausgehen, dass sie in Maven ausgeführt werden.

Eine der besten Möglichkeiten, mit temporären Dateien umzugehen, ist die Verwendung von Junit-Regeln. Auf diese Weise können Sie sich darauf verlassen, dass die Regel für Sie aufräumt.

Um es vorweg zu sagen, ich bin strikt dagegen, solche Dinge in Unit-Tests zu tun. Ich habe das nicht wirklich ausprobiert, aber es sollte funktionieren:

Angenommen, Sie verwenden das todsichere Plugin aus dem zitierten Dokument, mit dem Sie auf das Basisverzeichnis des zu testenden Projekts zugreifen können System.getProperty("basedir"). Holen Sie es und erstellen Sie Dateien unter basedir/target.

Ein “angemessenerer” Weg (da wir möglicherweise das Ausgabeverzeichnis auf etwas anderes konfiguriert haben, können Sie die todsichere Plugin-Konfiguration in etwa so ändern:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <systemPropertyVariables>
            <myOutDir>${project.build.outputDirectory}</myOutDir>
        </systemPropertyVariables>
    </configuration>
</plugin>

Dann können Sie das tatsächliche Ausgabeverzeichnis erhalten System.getProperty("myOutDir") in deiner Prüfung.

Benutzer-Avatar
AlexR

Temporäre Dateien sollten im temporären Verzeichnis erstellt werden. Rufen Sie es mit Anruf ab System.getProperty("java.io.tmpdir")

Temporäre Dateien sollten temporär sein, dh entfernt werden, wenn sie nicht benötigt werden. Um dies zu erreichen, vergessen Sie nicht, es zu löschen finally Block oder in Code, der nach dem Test ausgeführt wird, dh:

File tmpFile = ...
try {
   // deal with tempFile
} finally {
    tempFile.delete();
}

und/oder

public class MyTestCase {
    private File tmpFile = null;

    @Before
    public void setUp() {
        tmpFile = ...;
    }

    @Test
    public void setUp() {
        // deal with tmpFile
    }

    @After
    public void setUp() {
        tmpFile.delete();
    }
}

Verwenden File.createTempFile(String prefix, String suffix) wenn es möglich ist, dh Sie können dann eine Datei mit speziellem Namen verwenden, die von generiert wird createTempFile().

Verwenden file.deleteOnExit(). Dadurch wird ein Hook erstellt, der die Datei automatisch entfernt, wenn JVM beendet wird. Die Datei bleibt nur erhalten, wenn JVM damit beendet wurde kill -9also hatte es keine Chance, Shutdown-Code auszuführen.

Benutzer-Avatar
dpelisek

Seit JUnit 5 können Sie verwenden @TempDir. Sie wird (einschließlich ihres Inhalts) nach dem/den Test(s) gelöscht.

entweder ein temporäres Verzeichnis für jeden Test:

@Test
void testWithTempFiles(@TempDir Path tempDir) 
    Path file = dir.resolve("temp_file.txt");
    ...
}

oder ein einzelner für alle Tests in der Klasse:

@TempDir
static Path tempDir

@Test
void testWithTempFiles() 
    Path file = dir.resolve("temp_file.txt");
    ...
}

1202220cookie-checkWas ist der richtige Weg, um während Unit-Tests mit Maven in temporäre Dateien zu schreiben?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy