209 votes

Comment utiliser Mockito avec JUnit5

Comment puis-je utiliser l'injection avec Mockito et JUnit 5 ?

Dans JUnit4, je peux simplement utiliser la fonction @RunWith(MockitoJUnitRunner.class) Annotation. Dans JUnit5, il n'y a pas de @RunWith Annotation ?

313voto

Nicolai Points 17516

Il existe différentes façons d'utiliser Mockito - je vais les passer en revue une par une.

Manuellement

Création manuelle de mocks avec Mockito::mock fonctionne quelle que soit la version de JUnit (ou du cadre de test, d'ailleurs).

Basé sur l'annotation

Utilisation de la @Mock -et l'appel correspondant à MockitoAnnotations::initMocks à créer des modèles fonctionne quelle que soit la version de JUnit (ou du cadre de test d'ailleurs, mais Java 9 pourrait interférer ici, selon que le code de test se retrouve dans un module ou non).

Extension Mockito

JUnit 5 a un modèle d'extension puissant et Mockito en a récemment publié un sous le groupe / l'artefact ID org.mockito : mockito-junit-jupiter .

Vous pouvez appliquer l'extension en ajoutant @ExtendWith(MockitoExtension.class) à la classe de test et d'annoter les champs fantaisie avec @Mock . De MockitoExtension JavaDoc :

@ExtendWith(MockitoExtension.class)
public class ExampleTest {

    @Mock
    private List list;

    @Test
    public void shouldDoSomething() {
        list.add(100);
    }

}

La documentation de MockitoExtension décrit d'autres façons d'instancier les mocks, par exemple avec l'injection de constructeur (si vous rpefer les champs finaux dans les classes de test).

Pas de règles, pas de coureurs

Les règles et les runners de JUnit 4 ne fonctionnent pas dans JUnit 5, donc les MockitoRule et le Coureur Mockito ne peut pas être utilisé.

7 votes

Il existe désormais une extension officielle de Mockito Junit5 qui est l'équivalent de MockitoJUnitRunner -> mockito-junit-jupiter

1 votes

Lorsque l'extension officielle pour Mockito a été publiée, j'ai écrit un article de blog avec plus de détails sur la façon de la configurer et de l'utiliser : solidsoft.wordpress.com/2018/03/27/

0 votes

Est-ce que la méthode annotée avec @Test doit être publique ou "paquet privé" est suffisant ?

86voto

Jonathan Points 5620

Utilisez la fonction MockitoExtension . L'extension est contenue dans un nouvel artefact mockito-junit-jupiter :

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>2.23.4</version>
    <scope>test</scope>
</dependency>

Il vous permet d'écrire des tests comme vous l'auriez fait avec JUnit 4 :

import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;

@ExtendWith(MockitoExtension.class)
class MyTest {

    @Mock
    private Foo foo;

    @InjectMocks
    private Bar bar; // constructor injection

    ...
}

16 votes

@ExtendWith(MockitoExtension.class) est équivalent à @RunWith(MockitoJUnitRunner.class) de la JUnit4

0 votes

Puis-je faire des appels multiples de la méthode avec des valeurs de retour différentes sur la méthode d'un objet Mock en utilisant MockitoExtension.class dans JUnit5

0 votes

@RajHassani Oui, vous pouvez, voir ici .

13voto

davidh Points 107

Il y a plusieurs façons de procéder, mais la plus propre et qui respecte également la philosophie de JUnit 5 est de créer un fichier org.junit.jupiter.api.extension.Extension pour Mockito.

1) Création manuelle de mocks fait perdre le bénéfice des vérifications supplémentaires de Mockito pour s'assurer que vous utilisez correctement le framework.

2) Appel MockitoAnnotations.initMocks(this) dans chaque classe de test est du code passe-partout que nous pourrions éviter.
Et faire cette configuration dans une classe abstraite n'est pas non plus une bonne solution.
Il couple chaque classe de test à une classe de base.
Si ensuite vous avez besoin d'une nouvelle classe de test de base pour de bonnes raisons, vous finissez avec une hiérarchie de classe à 3 niveaux. Veuillez éviter cela.

3) Test Rules est une spécificité de JUnit 4.
N'y pense même pas.
Et le documentation est clair à ce sujet :

Cependant, si vous avez l'intention de développer une nouvelle extension pour JUnit 5, veuillez utilisez le nouveau modèle d'extension de JUnit Jupiter au lieu du modèle basé sur des règles de JUnit 4. de JUnit 4.

4) Test Runner n'est pas vraiment le moyen d'étendre le cadre JUnit 5.
JUnit 5 a simplifié l'enfer des Runners de JUnit 4 en fournissant un modèle d'extension pour écrire des tests grâce aux Extensions de JUnit 5.
N'y pense même pas.

Favorisez donc le org.junit.jupiter.api.extension.Extension manière.


EDIT : En fait, Mockito emballe une extension jupiter : mockito-junit-jupiter

Ensuite, très simple à utiliser :

import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class FooTest {
     ...    
}

Voici un complément à l'excellente réponse de Jonathan.

En ajoutant comme dépendance le mockito-junit-jupiter artefact, l'utilisation de @ExtendWith(MockitoExtension.class) a produit l'exception suivante lors de l'exécution du test :

java.lang.NoSuchMethodError : org.junit.platform.commons.support.AnnotationSupport.findAnnotation(Ljava/util/Optional;Ljava/lang/Class ;)Ljava/util/Optional ;

Le problème est que mockito-junit-jupiter dépend de deux bibliothèques indépendantes. Par exemple pour mockito-junit-jupiter:2.19.0 :

<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  <version>2.19.0</version>
  <scope>compile</scope>
</dependency>
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-api</artifactId>
  <version>5.1.0</version>
  <scope>runtime</scope>
</dependency>

Le problème est que j'ai utilisé junit-jupiter-api:5.0.1 .

Alors que junit-jupiter-api se déplace encore souvent en termes d'API, assurez-vous que vous dépendez de la même version de junit-jupiter-api que mockito-junit-jupiter dépend.

1 votes

Pourquoi ne pas mockito-junit-jupiter tirer la bonne version de junit-jupiter-api ?

0 votes

@haelix Parce que la stratégie de version utilisée pour cette dépendance repose sur la bibliothèque Mockito. Regardez la version ici mockito-junit-jupiter:2.19.0 . Alors que les versions de JUnit Jupiter commencent par 5 . mockito-junit-jupiter aurait dû spécifier dans son identifiant d'artefact les deux choses (version de Mockito et version de JUnit Jupiter) pour rendre les choses plus claires. Par exemple mockito-junit-jupiter-5.1:2.19.0 pour indiquer que la bibliothèque est conçue pour JUnit Jupiter 5.1.

0 votes

MockitoExtension ne semble pas exister dans mockito-core version 3.0.0.

4voto

Daniel Käfer Points 1850

Vous devez utiliser le nouveau @ExtendWith annotation.

Malheureusement, il n'y a pas encore d'extension disponible. Sur github vous pouvez voir une mise en œuvre bêta pour l'extension. à titre d'exemple test de démonstration .

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