[JAVA] Utilisation minimale de Mockito

introduction

J'ai décidé d'utiliser ** JUnit + Mockito + PowerMock ** dans le projet sur lequel je travaille actuellement. En premier lieu, tout m'est inconnu, qui n'ai jamais touché JUnit lui-même.

Même si vous essayez gg avec "** Mockito **", il existe peu d'articles qui expliquent que des personnes sans connaissances peuvent l'utiliser immédiatement. Ou plutôt ** je n'ai pas beaucoup de japonais! ** ** C'est difficile à comprendre sans explication en japonais. ..

Alors, j'écris cet article pour moi qui ne savais rien car j'ai finalement avalé un peu récemment.

Cette fois, c'est l'édition ** Mockito **.

En particulier, j'écrirai sur le cas où vous voulez vous moquer d'une méthode d'une classe différente de la classe testée.

Ce que Mockito ne peut pas faire

Tout d'abord, il y a beaucoup de choses que Mockito ne peut pas faire. Ce n'est pas polyvalent et il n'y a qu'un nombre limité de méthodes qui peuvent être ridiculisées. Je ne peux pas me moquer

Ce sont les quatre types ci-dessus. (Peut-être) Je pense aussi que les classes abstraites ne peuvent pas être ridiculisées. (Peut-être)

Sinon, vous pouvez vous en moquer avec mockito (peut-être). Pour vous moquer des quatre ci-dessus, vous devez utiliser PowerMock séparément de Mockito.

Mock la classe avec la méthode que vous souhaitez appeler

Tout d'abord, pour appeler une méthode simulée, moquez-vous de la classe. Il existe ** 2 types de méthodes moqueuses **. Un seul d'entre eux va bien.

** ① Directement sous la classe @ Mock ** ** ② Utilisez la méthode mock () **

Java



public class TestClass {
  //① Directement sous la classe@Déclaration d'une instance fictive dans Mock
  @Mock
  private Entity entity; //Ceci est une déclaration uniquement, aucun objet fictif n'est créé
  
  @Test
  public void test001() {
     // ② mock()Utiliser la méthode
    Entity entity = mock(Entity.class); //Cela seul créera un objet simulé
  }
}

En cas de ** ① **, il est nécessaire d'initialiser séparément de cette déclaration. ** ② ** moquez la classe à chaque fois dans la classe de test. Il n'a pas besoin d'être initialisé.

Initialisation fictive

Dans le cas de @ Mock de ** ① **, l'objet fictif n'a pas encore été créé, il est donc nécessaire de ** initialiser **.

Java



public class class() {
  // @Motif simulé
  @Mock
  private ResultEntity entity;
  
  @Before // @Ajoutez une annotation Avant et exécutez chaque méthode de test avant l'exécution.
  private void initMocks() {
    MockitoAnnotations.initMocks(this); //Magie d'initialisation
  }
}

Je pense que la méthode ** ① ** est efficace lorsque ** il y a plusieurs cas de test et que la classe que vous voulez moquer apparaît plusieurs fois **.

Injecter une maquette dans la classe testée

Utilisez l'annotation @ InjectMocks pour injecter une simulation dans la classe testée directement sous la classe test.

public class TestClass {
  @Mock
  Entity entity; //Classe moquée

  @InjectMocks
  Human human; //Injecter une maquette dans la classe testée
}

Pour le moment, il est possible de se moquer d'elle puis de la tester. Lors de l'obtention de la couverture, ** elle ne sera pas de 100% à moins que l'instance de la classe testée ne soit appelée **, donc si vous souhaitez définir la couverture sur 100%

   @InjectMocks
  Human human = new Human();

C'est normal d'écrire comme ça.

Maintenant que nous nous sommes moqués de la classe, nous nous moquerons en fait de la méthode pour chaque cas ci-dessous.

Pour les méthodes publiques avec une valeur de retour

chaîne publique etc. Dans ce cas, il y a ~~ pourquoi ~~ ** 2 types ** de comment se moquer de la méthode.

1. puis méthode

Mockito.when(Instance fictive).Méthode(Argument arbitraire).thenReturn(Toute valeur de retour);
//Renvoie ce retour lorsque la méthode de la classe simulée est appelée

La méthode est maintenant moquée, et la méthode n'est pas réellement exécutée et n'est qu'une simulation qui renvoie une valeur de retour arbitraire.

Au fait, la tête «Mockito» peut être avec ou sans elle. Puisque PowerMock est écrit de la même manière, ** il est nécessaire de l'utiliser correctement lorsque vous l'utilisez en même temps **, donc je pense que ce sera plus facile à comprendre si vous le mettez dans votre tête.

2. faire la méthode

Mockito.doReturn(Toute valeur de retour).when(Instance fictive).Méthode(Argument arbitraire);
//Je retournerai cette valeur de retour lorsque la méthode de la classe simulée sera appelée

Les deux ① et ② se comportent exactement de la même manière. Comme expliqué ci-dessous, ** alors la méthode peut ne pas être capable de le gérer **, il semble donc qu'il n'y ait pas d'erreur si vous unifiez avec la méthode do.

Pour les méthodes publiques void sans valeur de retour

public void Dans ce cas, il ne peut être décrit que par la ** méthode do **.

Mockito.doNothing().when(Instance fictive).Méthode(Argument arbitraire);
//Il ne renvoie rien, quand une méthode de classe fictive est appelée

Il ne semble pas y avoir de méthode appelée thenNothing ().

Validez les arguments de la méthode simulée (ArgumentCaptor)

Puisque la méthode est moquée, il n'est pas nécessaire de la vérifier, mais je pense qu'il sera nécessaire de vérifier que les arguments passés à la méthode moquée ** sont corrects **.

Vous pouvez utiliser ʻArgument Captor` dans un tel cas.

ArgumentCaptor<Moule>variable= ArgumentCaptor.forClass(Moule.class);
// forClass()Créer un conteneur (variable) de ce type avec une méthode

méthode capture ()

Si vous passez la variable ci-dessus comme argument lorsque vous vous moquez d'une méthode, l'argument réellement passé sera capturé et stocké dans la variable. A ce moment, ajoutez la méthode capture ().

Mockito.doReturn("Valeur de retour").when(classe).Méthode(variable.capture());
// forClass()Créer un conteneur (variable) de ce type avec une méthode

La variable contient maintenant les arguments passés dans la source réelle.

Acquisition des informations de capture stockées

variable.getValue(); // ①
variable.getAllValues().get(index); // ②

En utilisant l'une de ces méthodes, vous pouvez obtenir la valeur en fonction du type de la variable.

** ① ** Si vous ne voulez vérifier qu'un seul argument, vous pouvez obtenir les informations stockées par la méthode getValue ().

** ② ** ArgumentCaptor peut être passé à ** arguments plusieurs fois et peut stocker autant de résultats qu'il y a d'arguments **. (Uniquement pour le même type.)

Dans ce cas, il est stocké sous la forme d'un tableau, donc récupérez toutes les valeurs avec la méthode getAllValues (). Vous pouvez obtenir la valeur de l'un d'eux avec get (index).

En fait, si vous réutilisez les variables, il sera difficile de déterminer quel nombre va à quel argument, donc en gros ** déclarez le contenu de ʻArgumentCaptor` autant que le nombre d'arguments ** Je pense qu'il vaut mieux le faire.

ArgumentCaptor<String> str = ArgumentCaptor.forClass(String.class);
Mockito.doReturn("Valeur de retour").when(Class).getStr(str.capture());
assertTaht(str.getValue(), is(Valeur attendue de l'argument));

Je pense que ça ressemblera à ça.

Vérifiez le nombre d'appels de méthode simulés

Si vous vous moquez d'une méthode, elle ne sera pas réellement appelée, vous devrez peut-être ** vérifier que la méthode simulée est appelée correctement **.

La méthode verify () est utilisée à ce moment-là.

Mockito.verify(Instance fictive, times(index)).Méthode simulée(argument);

Vous pouvez vérifier combien de fois la méthode a été appelée en passant la valeur attendue comme instance fictive comme premier argument de la méthode verify (), la méthode times () comme deuxième argument et int comme argument.

Les méthodes sans valeur de retour peuvent être simulées uniquement avec verify ()

Que voulez-vous dire

Se moquer d'une méthode sans valeur de retour est comme décrit dans [Pour une méthode publique void sans valeur de retour](# Pour une méthode publique void sans valeur de retour).

Si vous voulez vérifier le nombre d'appels de méthode, vous n'avez pas à faire à la fois doNothing () et verify (), vous pouvez faire les deux en même temps avec juste ** verify (). ** **

Plutôt que de le faire en même temps, cela signifie qu'il a été simulé comme une méthode sans valeur de retour au moment de ** verify () **.

La seule mise en garde est que ** les méthodes avec des valeurs de retour ne peuvent pas être simulées avec verify () **.

En effet, verify () ** ne peut pas simuler la valeur de retour **.

// doNothing()Même si tu ne te moques pas, c'est ok
Mockito.verify(Instance fictive, times(index)).Méthode simulée();

Au fait, dans le cas ci-dessus + si vous voulez vérifier l'argument

// doNothing()Même si vous ne vous moquez pas, c'est ok
Mockito.verify(Instance fictive, times(index)).Méthode simulée(variable.capture());

Ce faisant, l'argument peut également être stocké à ce moment.

finalement

Si vous vous en souvenez, je pense que vous pourrez vous battre dans une certaine mesure. J'ai l'intention d'écrire des moqueries d'autres méthodes de la même classe et des moqueries de nouvelles dans le futur.

référence

[Java] Comment boire Mockito (Introduction)

Recommended Posts

Utilisation minimale de Mockito
[Java] Utilisation de Mirage-Basic de SQL
Utilisation super basique d'Eclipse
Validation des messages du journal à l'aide de mockito
Utilisation de base de Java Facultatif Partie 1
Utilisation correcte de Mockito et PowerMock
[Rails] Différences et utilisation de each_with_index et each.with_index
De l'introduction à l'utilisation de byebug
[Utilisation spécifique de before_action] Refactoring des rails
Utilisation de base et exemple de code d'énumération
Comment utiliser Colaboratory différemment pendant peut-être une minute (essayez Kotlin)
[Ruby] Distinction et utilisation des boucles dans Ruby
Introduction et explication de l'utilisation de Font Awesome