junit5-logo.png

Pour les cas où il faut tester les textes affichés à l'écran, voici une façon de procéder avec JUnit 5 ...

Le principe est simple: détourner l'affichage vers un flux que l'on va pouvoir tester. On commence donc par importer les annotations dont on va avoir besoin:

 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;

Puis les matchers hamcrest pour faciliter la lecture des tests:

 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.MatcherAssert.assertThat;

Ensuite les assertions JUnit 5:

 
 import static org.junit.jupiter.api.Assertions.*;

Et enfin les flux texte:

 import java.io.PrintStream;
 import java.io.ByteArrayOutputStream;

Maintenant la classe de test qui instancie la classe à tester:

 class maClasseATesterTest {
 
   private maClasseATester classeTestee = new maClasseATester();

Puis on récupère la sortie standard pour pouvoir la restaurer à l'issue:

   private final PrintStream standardOut = System.out;

Puis on prépare le flux de sortie qui sera utilisé pendant les tests:

   private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream();

Enfin, avant chaque test, on détourne la sortie standard vers notre flux de sortie:

 
   @BeforeEach
   public void beforeEachTest() {
     System.setOut(new PrintStream(outputStreamCaptor));
   }

Voici enfin notre test:

 
   @Test
   @DisplayName("Test du message affiché")
   public void testDuMessageAffiche() {
     classeTestee.afficherBonjour();
     assertThat(outputStreamCaptor.toString(), containsString("Bonjour"));
   }

Enfin, à l'issue, plus qu'à restaurer l'affichage vers le flux standard que nous avions pris la précaution de sauvegarder au début:

   @AfterEach
   public void tearDown() {
     System.setOut(standardOut);
   }
 }

Il ne reste plus qu'à lancer les tests, par exemple:

 $ gradle test

Amélioration

Le fait est que détourner et restaurer le flux à chaque test peut s'avérer peu efficace. Du coup, on va le faire une fois avant le premier test puis restaurer une fois le dernier test exécuté. Attention toutefois, avec JUnit 5, les méthodes préfixées avec @BeforeAll ou @AfterAll doivent être statiques, d'où les changements:

On modifie d'abord les imports:

 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.AfterAll;

puis la classe de test:

 class maClasseATesterTest {
 
   private maClasseATester classeTestee = new maClasseATester();
 
   private static final PrintStream standardOut = System.out;
   private static final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream();
 
   @BeforeAll
   public static void beforeEachTest() {
     System.setOut(new PrintStream(outputStreamCaptor));
   }

et:

   @AfterAll
   public static void tearDown() {
     System.setOut(standardOut);
   }
 }