Répertoires temporaires dans JUnit 5 Tests
JUnit 4 TemporaryFolder
@Rule
a permis aux développeurs de créer des tests en utilisant des répertoires temporaires. Avec JUnit 5, le @Rule
s ne sont pas pris en charge, par conséquent, le test des fichiers et des répertoires a nécessité un peu de travail supplémentaire. Heureusement, avec JUnit 5.4, il existe une nouvelle extension intégrée pour gérer les répertoires temporaires dans les tests. Et il est extrêmement facile à utiliser.
Travaillez-vous toujours avec JUnit 4 ? Voir mon article précédent sur les tests avec des fichiers et des répertoires dans JUnit 4 avec TemporaryFolder @Rule
@TempDir
@org.junit.jupiter.api.io.TempDir
l'annotation peut être utilisée pour annoter un champ de classe ou un paramètre dans un cycle de vie (par exemple @BeforeEach
) ou méthode de test de type File
ou Path
. Une fois cela fait, le répertoire temporaire sera créé. Le répertoire avec son contenu créé lors de l'exécution du test sera supprimé une fois l'exécution de la méthode ou de la classe de test terminée.
Le code à tester
Dans cet exemple simple, nous allons tester le FileWriter
classe, qui a une seule méthode écrivant le contenu du texte dans un nouveau fichier :
01020304050607080910 | public class FileWriter { public void writeTo(String path, String content) throws IOException { Path target = Paths.get(path); if (Files.exists(target)) { throw new IOException( "file already exists" ); } Files.copy( new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)), target); } } |
@TemDir comme paramètre de méthode de test
Dans cet exemple, nous annoterons le paramètre de test avec @TempDir
annotation :
0102030405060708091011121314151617 | import org.junit.jupiter.api.io.TempDir; @Test void writesContentToFile( @TempDir Path tempDir) throws IOException { // arrange Path output = tempDir .resolve( "output.txt" ); // act fileWriter.writeTo(output.toString(), "test" ); // assert assertAll( () -> assertTrue(Files.exists(output)), () -> assertLinesMatch(List.of( "test" ), Files.readAllLines(output)) ); } |
@TempDir comme champ d'instance
0102030405060708091011121314151617181920212223242526 | import org.junit.jupiter.api.io.TempDir; class FileWriterTest { private FileWriter fileWriter = new FileWriter(); @TempDir Path tempDir; @BeforeEach void beforeEach() { assertTrue(Files.isDirectory( this .tempDir)); } @RepeatedTest ( 3 ) void throwsErrorWhenTargetFileExists() throws IOException { // arrange Path output = Files.createFile( tempDir.resolve( "output.txt" ) ); // act & assert IOException expectedException = assertThrows(IOException. class , () -> fileWriter.writeTo(output.toString(), "test" )); assertEquals( "file already exists" , expectedException.getMessage()); } } |
Sur la base de l'exemple ci-dessus, nous pouvons voir que chaque répétition du test utilise un nouveau répertoire temporaire (selon le cycle de vie standard de la classe de test), par conséquent, la section d'arrangement de la méthode s'exécute sans erreur.
Répertoire temporaire partagé
S'il est nécessaire de partager un répertoire temporaire entre les méthodes de test, nous pouvons créer un champ statique et réutiliser le répertoire temporaire comme dans l'exemple ci-dessous :
0102030405060708091011121314151617181920212223242526 | import org.junit.jupiter.api.io.TempDir; class FileWriterTest { private FileWriter fileWriter = new FileWriter(); @TempDir static Path tempDir; @BeforeAll static void setUp() { assertTrue(Files.isDirectory(tempDir)); } @RepeatedTest ( 3 ) void throwsErrorWhenTargetFileExists(RepetitionInfo repetitionInfo) throws IOException { // arrange Path output = Files.createFile( tempDir.resolve(repetitionInfo.getCurrentRepetition() + "_output.txt" ) ); // act & assert IOException expectedException = assertThrows(IOException. class , () -> fileWriter.writeTo(output.toString(), "test" )); assertEquals( "file already exists" , expectedException.getMessage()); } } |
Veuillez noter que la section organiser de la méthode de test crée un nom de fichier unique par exécution (en utilisant le compteur de répétition actuel) sinon le FileAlreadyExistsException
aurait été jeté.
Résumé
Avec @TempDir
vous avez la possibilité de travailler facilement avec des répertoires temporaires dans les tests. Il n'y a pas de magie ici :vous annotez Path
ou File
objets et injectez au fur et à mesure que vous en avez besoin. Le reste est pris en charge par JUnit pour vous.
Retrouvez les exemples dans mon référentiel GitHub ici :https://github.com/kolorobot/junit5-samples/tree/master/junit5-built-in-extensions