Comment fonctionne Junit @Rule?

195

Je veux écrire des cas de test pour une masse de code, j'aimerais connaître les détails de la @Rulefonction d'annotation JUnit , afin de pouvoir l'utiliser pour écrire des cas de test. Veuillez fournir quelques bonnes réponses ou liens, qui donnent une description détaillée de ses fonctionnalités à travers un exemple simple.

Dipak
la source
je suis déjà passé par ce lien http://cwd.dhemery.com/2011/01/what-junit-rules-are-good-for/
Dipak
J'ai trouvé cet article@Rule plutôt bien expliqué , en particulier la dernière section "La séquence des événements en détail"
Peter Perháč
Je pense que c'est similaire au concept d'injection, n'est-ce pas?
Chao
Merci d'avoir partagé ce lien. Une chose n'est pas claire. Quand l'instruction DEFAULT.evaluate () est-elle appelée? Est-il appelé avant l'évaluation () de toutes les règles ou après toutes? J'imagine après tous.
MasterJoe2
@ testerjoe2 vous pouvez choisir d'ignorer complètement l'instruction par défaut. Vous pouvez choisir de lui déléguer ou simplement le remplacer par une autre déclaration de votre choix. Il n'est pas appelé , vous pouvez l'appeler ou non. C'était au point 10: "La méthode evaluer () de l'instruction de capture d'écran appelle la méthode evaluer () de l'instruction par défaut."
Peter Perháč

Réponses:

156

Les règles sont utilisées pour ajouter des fonctionnalités supplémentaires qui s'appliquent à tous les tests d'une classe de test, mais d'une manière plus générique.

Par exemple, ExternalResource exécute le code avant et après une méthode de test, sans avoir à utiliser @Beforeet @After. Utiliser un ExternalResourceplutôt que @Beforeet @Afterdonne des opportunités pour une meilleure réutilisation du code; la même règle peut être utilisée à partir de deux classes de test différentes.

La conception était basée sur: les intercepteurs dans JUnit

Pour plus d'informations, consultez le wiki JUnit: Règles .

Matthew Farwell
la source
1
Correction: "Par exemple, ExternalResource exécute du code avant et après une classe de test ." Il y a quelque chose à propos de l'utilisation de apply () pour faire exécuter ExternalResource entre les tests.
derekm
62

Les règles Junit fonctionnent sur le principe de l'AOP (programmation orientée aspect). Il intercepte la méthode de test, offrant ainsi la possibilité de faire certaines choses avant ou après l'exécution d'une méthode de test particulière.

Prenons l'exemple du code ci-dessous:

public class JunitRuleTest {

  @Rule
  public TemporaryFolder tempFolder = new TemporaryFolder();

  @Test
  public void testRule() throws IOException {
    File newFolder = tempFolder.newFolder("Temp Folder");
    assertTrue(newFolder.exists());
  }
} 

Chaque fois que la méthode de test ci-dessus est exécutée, un dossier temporaire est créé et il est supprimé après l'exécution de la méthode. Voici un exemple de règle prête à l'emploi fournie par Junit.

Un comportement similaire peut également être obtenu en créant nos propres règles. Junit fournit l'interface TestRule, qui peut être implémentée pour créer notre propre règle Junit.

Voici un lien utile pour référence:

Abhishek Mohanty
la source
4
donc il est supprimé sans écrire de code pour supprimer / effacer l'objet?
Dror
regardez la source de github.com/junit-team/junit4/blob/master/src/main/java/org/… , le dossier est créé dans la méthode de rappel before () et supprimé dans la méthode de rappel after (). ..
Pierluigi Vernetto
1
Pour les personnes qui n'ont peut-être pas compris pourquoi le TemporaryFolder est supprimé, c'est parce qu'il s'agit d'un TemporaryFolder fourni par Junit pour servir de dossier temporaire qui est automatiquement supprimé - c'est-à-dire que l'étape de démontage fait partie de la classe TemporaryFolder elle-même.
Mindaugas Bernatavičius
18

L'explication de son fonctionnement:

JUnit encapsule votre méthode de test dans un objet Statement ainsi une instruction et Execute()exécute votre test. Ensuite, au lieu d'appeler statement.Execute()directement pour exécuter votre test, JUnit transmet l'instruction à une TestRule avec l' @Ruleannotation. La fonction "apply" de TestRule retourne une nouvelle instruction donnée la déclaration avec votre test. La Execute()méthode de la nouvelle instruction peut appeler la méthode d'exécution de l'instruction de test (ou non, ou l'appeler plusieurs fois) et faire ce qu'elle veut before and after.

Maintenant, JUnit a une nouvelle instruction qui fait plus que simplement exécuter le test, et il peut à nouveau la transmettre à d'autres règles avant d'appeler enfin Execute.

Alexander Taylor
la source
2
L'instruction a la méthode évaluer pas exécuter.
Hemanth
0

Les règles sont utilisées pour améliorer le comportement de chaque méthode de test de manière générique. La règle Junit intercepte la méthode de test et nous permet de faire quelque chose avant qu'une méthode de test ne commence l'exécution et après qu'une méthode de test ait été exécutée.

Par exemple, en utilisant la règle @Timeout , nous pouvons définir le délai d'expiration pour tous les tests.

public class TestApp {
    @Rule
    public Timeout globalTimeout = new Timeout(20, TimeUnit.MILLISECONDS);

    ......
    ......

 }

La règle @TemporaryFolder est utilisée pour créer des dossiers temporaires, des fichiers. Chaque fois que la méthode de test est exécutée, un dossier temporaire est créé et il est supprimé après l'exécution de la méthode.

public class TempFolderTest {

 @Rule
 public TemporaryFolder tempFolder= new TemporaryFolder();

 @Test
 public void testTempFolder() throws IOException {
  File folder = tempFolder.newFolder("demos");
  File file = tempFolder.newFile("Hello.txt");

  assertEquals(folder.getName(), "demos");
  assertEquals(file.getName(), "Hello.txt");

 }


}

Vous pouvez voir des exemples de certaines règles intégrées fournies par junit sur ce lien .

Hari Krishna
la source