Java >> Java tutorial >  >> Tag >> JUnit

JUnit 5 Midlertidig Directory Support

1. Oversigt

Når vi tester, har vi ofte brug for adgang til en midlertidig fil. Det kan dog være besværligt at administrere oprettelsen og sletningen af ​​disse filer selv.

I denne hurtige tutorial, vi tager et kig på, hvordan JUnit 5 afhjælper dette ved at levere TempDirectory-udvidelsen .

For en dybdegående guide til test med JUnit, se vores fremragende guide til JUnit 5.

2. TempDirectory-udvidelsen

Fra version 5.4.2 giver JUnit 5 TempDirectory-udvidelsen. Det er dog vigtigt at bemærke, at dette officielt stadig er en eksperimentel funktion, og at vi opfordres til at give feedback til JUnit-teamet.

Som vi vil se senere, kan vi bruge denne udvidelse til at oprette og rydde op i en midlertidig mappe til en individuel test eller alle test i en testklasse .

Normalt, når vi bruger en udvidelse, skal vi registrere den fra en JUnit 5-test ved hjælp af @ExtendWith anmærkning. Men dette er ikke nødvendigt med TempDirectory-udvidelsen, som er indbygget og registreret som standard.

3. Maven Dependencies

Lad os først og fremmest tilføje de projektafhængigheder, vi skal bruge til vores eksempler.

Bortset fra JUnit 5-hovedbiblioteket junit-jupiter-engine vi skal også bruge junit-jupiter-api bibliotek:

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.8.1</version>
    <scope>test</scope>
</dependency>

Som altid kan vi få den seneste version fra Maven Central.

Ud over dette skal vi også tilføje junit-jupiter-parametrene afhængighed:

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-params</artifactId>
    <version>5.8.1</version>
    <scope>test</scope>
</dependency>

Igen kan vi finde den seneste version i Maven Central.

4. Brug af @TempDir Anmærkning

For at bruge TempDirectory-udvidelsen skal vi gøre brug af @TempDir anmærkning . Vi kan kun bruge denne annotation med følgende to typer:

  • java.nio.file.Path
  • java.io.File

Faktisk, hvis vi forsøger at bruge det med en anden type, så en org.junit.jupiter.api.extension.ParameterResolutionException vil blive smidt.

Lad os derefter udforske flere forskellige måder at bruge denne annotation på.

4.1. @TempDir som en metodeparameter

Lad os begynde med at se, hvordan man injicerer en parameter, der er kommenteret med @TempDir i en enkelt testmetode :

@Test
void givenTestMethodWithTempDirectory_whenWriteToFile_thenContentIsCorrect(@TempDir Path tempDir) 
  throws IOException {
    Path numbers = tempDir.resolve("numbers.txt");

    List<String> lines = Arrays.asList("1", "2", "3");
    Files.write(numbers, lines);

    assertAll(
      () -> assertTrue("File should exist", Files.exists(numbers)),
      () -> assertLinesMatch(lines, Files.readAllLines(numbers)));
}

Som vi kan se, opretter og skriver vores testmetode en fil kaldet numbers.txt i den midlertidige mappe tempDir .

Vi tjekker derefter, at filen findes, og at indholdet stemmer overens med det, der oprindeligt blev skrevet. Rigtig fint og enkelt!

4.2. @TempDir på et instansfelt

I dette næste eksempel vil vi annotere et felt i vores testklasse ved hjælp af @TempDir anmærkning:

@TempDir
File anotherTempDir;

@Test
void givenFieldWithTempDirectoryFile_whenWriteToFile_thenContentIsCorrect() throws IOException {
    assertTrue("Should be a directory ", this.anotherTempDir.isDirectory());

    File letters = new File(anotherTempDir, "letters.txt");
    List<String> lines = Arrays.asList("x", "y", "z");

    Files.write(letters.toPath(), lines);

    assertAll(
      () -> assertTrue("File should exist", Files.exists(letters.toPath())),
      () -> assertLinesMatch(lines, Files.readAllLines(letters.toPath())));
}

Denne gang bruger vi en java.io.File til vores midlertidige bibliotek. Igen skriver vi nogle linjer og kontrollerer, at de er skrevet med succes.

Hvis vi derefter skulle bruge denne enkelt reference igen i andre testmetoder, ville hver test bruge sin egen midlertidige mappe .

4.3. En delt midlertidig mappe

Nogle gange vil vi måske dele en midlertidig mappe mellem testmetoder .

Vi kan gøre dette ved at erklære vores felt statisk :

@TempDir
static Path sharedTempDir;

@Test
@Order(1)
void givenFieldWithSharedTempDirectoryPath_whenWriteToFile_thenContentIsCorrect() throws IOException {
    Path numbers = sharedTempDir.resolve("numbers.txt");

    List<String> lines = Arrays.asList("1", "2", "3");
    Files.write(numbers, lines);

    assertAll(
        () -> assertTrue("File should exist", Files.exists(numbers)),
        () -> assertLinesMatch(lines, Files.readAllLines(numbers)));
}

@Test
@Order(2)
void givenAlreadyWrittenToSharedFile_whenCheckContents_thenContentIsCorrect() throws IOException {
    Path numbers = sharedTempDir.resolve("numbers.txt");

    assertLinesMatch(Arrays.asList("1", "2", "3"), Files.readAllLines(numbers));
  }

Nøglepunktet her er, at vi bruger et statisk felt sharedTempDir som vi deler mellem de to testmetoder .

I den første test skriver vi igen nogle linjer til en fil kaldet numbers.txt . Så kontrollerer vi, at filen og indholdet allerede eksisterer i næste test.

Vi håndhæver også rækkefølgen af ​​testene via @Order annotation for at sikre, at adfærden altid er konsistent.

5. Gotchas

Lad os nu gennemgå nogle af de finesser, vi bør være opmærksomme på, når vi arbejder med TempDirectory-udvidelsen.

5.1. Oprettelse

Den nysgerrige læser derude vil højst sandsynligt undre sig over, hvor disse midlertidige filer egentlig er oprettet?

Nå, internt i JUnit TemporaryDirectory klasse gør brug af Files.createTempDirectory(String prefix) metode. På samme måde gør denne metode brug af standardsystemets midlertidige filbibliotek .

Dette er normalt angivet i miljøvariablen TMPDIR :

TMPDIR=/var/folders/3b/rp7016xn6fz9g0yf5_nj71m00000gn/T/

For eksempel, hvilket resulterer i en midlertidig filplacering:

/var/folders/3b/rp7016xn6fz9g0yf5_nj71m00000gn/T/junit5416670701666180307/numbers.txt

I mellemtiden, hvis den midlertidige mappe ikke kan oprettes, vil en ExtensionConfigurationException vil blive smidt efter behov. Eller som tidligere nævnt, en ParameterResolutionException .

5.2. Sletning

Når testmetoden eller klassen er afsluttet, og den midlertidige mappe går uden for scope, vil JUnit-rammeværket forsøge rekursivt at slette alle filer og mapper i den mappe og til sidst selve den midlertidige mappe.

Hvis der er et problem under denne sletningsfase, en IOException vil blive kastet, og testen eller testklassen mislykkes.

6. Konklusion

For at opsummere har vi i dette selvstudium udforsket TempDirectory-udvidelsen leveret af JUnit 5.

Først startede vi med at introducere udvidelsen og lærte, hvilke Maven-afhængigheder vi skal bruge for at bruge den. Dernæst så vi på flere eksempler på, hvordan man bruger udvidelsen fra vores enhedstests.

Til sidst så vi på adskillige gotchas, herunder hvor de midlertidige filer oprettes, og hvad der sker under sletning.

Som altid er den fulde kildekode til artiklen tilgængelig på GitHub.


Java tag