Mockito Strict Stubbing et l'exception de stubbing inutile

1. Vue d'ensemble

Dans ce rapide didacticiel, nous découvrirons l'exception Mockito UnnecessaryStubbingException . Cette exception est l'une des exceptions courantes que nous rencontrerons probablement lors de l'utilisation incorrecte des stubs.

Nous commencerons par expliquer la philosophie derrière le stubbing strict et pourquoi Mockito encourage son utilisation par défaut. Ensuite, nous examinerons exactement ce que signifie cette exception et dans quelles circonstances elle peut se produire. Pour conclure, nous verrons un exemple de la façon dont nous pouvons supprimer cette exception dans nos tests.

Pour en savoir plus sur les tests avec Mockito, consultez notre série complète Mockito.

2. Stubbing strict

Avec la version 1.x de Mockito, il était possible de configurer et d'interagir avec des simulacres sans aucune sorte de restriction. Cela signifiait qu'au fil du temps, les tests devenaient souvent trop compliqués et parfois plus difficiles à déboguer.

Depuis la version 2. +, Mockito a introduit de nouvelles fonctionnalités qui poussent le framework vers la «rigueur». Les principaux objectifs sous-jacents sont:

  • Détecter les stubs inutilisés dans le code de test
  • Réduisez la duplication du code de test et le code de test nécessaire
  • Promouvoir des tests plus propres en supprimant le code `` mort ''
  • Aide à améliorer la débuggabilité et la productivité

Suivre ces principes nous aide à créer des tests plus propres en éliminant le code de test inutile . Ils permettent également d'éviter les erreurs de copier-coller ainsi que d'autres oublis des développeurs.

Pour résumer, le stubbing strict signale les stubs inutiles, détecte l'inadéquation des arguments de stubbing et rend nos tests plus DRY (Don't Repeat Yourself). Cela facilite une base de code propre et maintenable.

2.1. Configuration des stubs stubs

Depuis Mockito 2. +, le stubbing strict est utilisé par défaut lors de l'initialisation de nos simulations en utilisant l'un des éléments suivants:

  • MockitoJUnitRunner
  • MockitoJUnit.rule ()

Mockito recommande fortement l'utilisation de l'un ou l'autre des éléments ci-dessus . Cependant, il existe également un autre moyen d'activer le stubbing strict dans nos tests lorsque nous n'utilisons pas la règle ou le runner Mockito:

Mockito.mockitoSession() .initMocks(this) .strictness(Strictness.STRICT_STUBS) .startMocking(); 

Un dernier point important à souligner est que dans Mockito 3.0, tous les stubbings seront «stricts» et validés par défaut.

3. Exemple d' exception non nécessaire

En termes simples, un stub inutile est un appel de méthode stub qui n'a jamais été réalisé lors de l'exécution du test.

Jetons un œil à un exemple simple:

@Test public void givenUnusedStub_whenInvokingGetThenThrowUnnecessaryStubbingException() { when(mockList.add("one")).thenReturn(true); // this won't get called when(mockList.get(anyInt())).thenReturn("hello"); assertEquals("List should contain hello", "hello", mockList.get(1)); }

Quand nous courons ce test unitaire, Mockito détectera le talon utilisé et jeter un UnnecessaryStubbingException :

org.mockito.exceptions.misusing.UnnecessaryStubbingException: Unnecessary stubbings detected. Clean & maintainable test code requires zero unnecessary code. Following stubbings are unnecessary (click to navigate to relevant line of code): 1. -> at com.baeldung.mockito.misusing.MockitoUnecessaryStubUnitTest.givenUnusedStub_whenInvokingGetThenThrowUnnecessaryStubbingException(MockitoUnecessaryStubUnitTest.java:37) Please remove unnecessary stubbings or use 'lenient' strictness. More info: javadoc for UnnecessaryStubbingException class.

Heureusement, le message d'erreur montre clairement quel est le problème ici. Nous pouvons également voir que le message d'exception nous renvoie même à la ligne exacte qui provoque l'erreur.

Pourquoi cela arrive-t-il? Eh bien, le premier lorsque l' invocation configure notre simulation pour retourner true lorsque nous appelons la méthode add avec l'argument «un» . Cependant, nous n'invoquons pas cette méthode pendant le reste de l'exécution du test unitaire.

Mockito nous dit que notre première ligne lorsque la ligne est redondante et peut-être que nous avons fait une erreur lors de la configuration de nos stubs.

Bien que cet exemple soit trivial, il est facile d'imaginer en se moquant d'une hiérarchie complexe d'objets comment ce type de message peut aider au débogage et être par ailleurs très utile.

4. Contournement du stubbing strict

Enfin, voyons comment contourner les stubs stubs. Ceci est également connu sous le nom de stubbing clément.

Parfois, nous devons configurer un stubbing spécifique pour qu'il soit indulgent tout en conservant tous les autres stubbings et simulacres pour utiliser un stubbing strict:

@Test public void givenLenientdStub_whenInvokingGetThenThrowUnnecessaryStubbingException() { lenient().when(mockList.add("one")).thenReturn(true); when(mockList.get(anyInt())).thenReturn("hello"); assertEquals("List should contain hello", "hello", mockList.get(1)); }

Dans l'exemple ci-dessus, nous utilisons la méthode statique Mockito.lenient () pour activer le stubbing indulgent sur la méthode add de notre liste fictive .

Les stubs clémentes contournent les règles de validation de «stubbing strict». Par exemple, lorsque le stubbing est déclaré indulgent, il ne sera pas vérifié pour d'éventuels problèmes de stubbing tels que le stubbing inutile décrit précédemment.

5. Conclusion

Dans ce bref article, nous avons commencé par présenter le concept de stubbing strict dans Mockito et compris la philosophie derrière pourquoi il a été introduit et pourquoi il est important.

Ensuite, nous avons examiné un exemple de l' exception UnnecessaireStubbingException avant de terminer avec un exemple d'activation du stubbing indulgent dans nos tests.

Comme toujours, le code source complet de l'article est disponible à l'adresse over sur GitHub.