35 votes

Comment éviter l'héritage dans les cas de test de JUnit ?

J'ai un certain nombre de cas de test dans JUnit. Tous ont besoin que le même code soit exécuté dans leur @BeforeClass méthode statique. C'est une duplication de code et j'essaie de m'en débarrasser. L'héritage est un moyen peu pratique de le faire. Existe-t-il d'autres mécanismes dans JUnit qui pourraient m'aider ?

PS. J'ai écrit ce billet de blog sur ce même sujet : http://www.yegor256.com/2015/05/25/unit-test-scaffolding.html

42voto

eskatos Points 1010

La façon dont JUnit compose du code réutilisable (au lieu d'en hériter), ce sont les règles.

Voir https://github.com/junit-team/junit/wiki/Rules

Voici un exemple stupide, mais vous comprendrez ce que je veux dire.

import org.junit.rules.TestRule;
import org.junit.runners.model.Statement;
import org.junit.runner.Description;

public class MyTestRule implements TestRule {
  @Override
  public Statement apply(final Statement statement, Description description) {
    return new Statement() {
      public void evaluate() throws Throwable {
        // Here is BEFORE_CODE
        try {
          statement.evaluate();
        } finally {
          // Here is AFTER_CODE
        }
      }
    };
  }
}

Vous pouvez ensuite utiliser votre règle de test comme suit :

import org.junit.Rule;

public class MyTest {
    @Rule
    public MyTestRule myRule = new MyTestRule();
}

BEFORE_CODE et AFTER_CODE seront alors exécutés autour de chacune de vos méthodes de test.

Si vous devez exécuter votre code une seule fois par classe, utilisez votre TestRule en tant que @ClassRule :

import org.junit.ClassRule;

public class MyTest {
    @ClassRule
    public static MyTestRule myRule = new MyTestRule();
}

Ahora, BEFORE_CODE y AFTER_CODE sera exécutée autour de chacune de vos classes de test.

@Règle n'est pas statique, @ClassRule est.

Une @ClassRule peut également être déclarée dans une Suite.

Notez que vous pouvez déclarer plusieurs règles dans une seule classe de test, c'est ainsi que vous composez les cycles de vie des tests aux niveaux des suites de tests, des classes de tests et des méthodes de tests.

Une règle est un objet que vous instanciez dans vos classes de test (statiquement ou non). Vous pouvez ajouter des paramètres de construction si nécessaire.

HTH

4voto

Suraj Chandran Points 12859

Si la méthode est une sorte d'utilitaire, séparez-la dans une classe différente avec une méthode statique et appelez cette méthode dans votre @BeforeClass.

J'insiste sur le fait qu'il ne faut pas utiliser l'héritage uniquement parce qu'il résout votre problème, mais lorsque cela a un sens dans votre hiérarchie de classes.

2voto

Marcin Michalski Points 934

Vous pouvez créer un programme de test

public class MyTestRunner extends BlockJUnit4ClassRunner {
  @Override
  protected Object createTest() throws Exception {
     Object test = super.createTest();
     doStuff();
  }

  public void doStuff(){
     //common code
  }
}

@RunWith(MyTestRunner.class)
public class MyTest1{
    @Test
    public void test1(){
      //test method
    }
}

1voto

Ryan Stewart Points 46960

Les méthodes statiques ne sont pas héritées, l'héritage n'est donc pas une option par défaut. Si vous voulez dire que vous déplacez la méthode vers une classe mère commune, cela semble être un mauvais choix puisque vous n'avez qu'un seul parent en Java. Une classe de support de test, quelle qu'elle soit, semblerait plus appropriée. Il est également possible que vous constatiez le besoin d'une classe test paramétré .

1voto

Cedric Beust Points 7209

Il n'y a absolument rien de mal à l'héritage dans ce cas, c'est même le seul moyen d'éviter de répéter ce code dans chaque sous-classe. Le fait que les méthodes @BeforeClass doivent être déclarées statiques dans JUnit est regrettable, mais cela ne devrait pas vous arrêter. Étendez la classe et vous aurez le code d'initialisation automatiquement exécuté pour vous sans avoir à faire quoi que ce soit.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X