Mockito et les classes primitives

Aujourd’hui, dans le cadre de mon développement, j’ai dû mettre en place des tests unitaires avec Mockito. Ces tests sont assez simples et ne posent pas trop de problèmes. Mais, j’ai découvert un comportement étrange de la part de Mockito concernant les attributs de type Boolean. Dans un objet mocké, un getter dont le retour n’est pas déterminé, retourne false au lieu de null qui serait la valeur par défaut de l’attribut. Je vais tenter de décrire la situation plus précisément par la suite.

Mockito et les classes primaires

Tests Mockito

Mon cas de test est le suivant. Je possède une classe Livraison et je vais y ajouter un attribut de type Boolean nommé evaluated. Je rajoute également les accesseurs normaux getEvaluated() et setEvaluated(). Cet attribut possède trois états différents : null à la création de l’objet, true ou false si la livraison est évaluée par l’utilisateur.

Une classe de service dépend de ce flag pour réaliser des traitements différents. Je souhaite donc tester les trois valeurs possibles de cet attribut. Pour cela, je vais mocker mon objet et utiliser les méthodes when().thenReturn() pour indiquer quelle valeur je souhaite voir utiliser à partir du mock.

Ceci fonctionne parfaitement et permet de réaliser les tests que l’on souhaite.

Perturbation : type Boolean

Avant de partager mon code, j’ai exécuté l’ensemble des tests de l’application pour détecter les régressions. Et certains sont effectivement apparues dans les tests de la méthode myMethod(). En y regardant de plus près, je remarque que la classe Livraison est mockée dans ces tests, mais sans prévoir le retour de la méthode getEvaluated(). Dans les tests en échec, la valeur retournée par ces objets mockés avec cette méthode non mockée est false. Pour moi, si le retour n’est pas prévu, la méthode va retourner la valeur par défaut du type Boolean. Dans ce cas présent, elle retournerait donc null.

En réalité, les objets créés par Mockito ont un comportement légèrement différent. Lorsque ce mock va tenter de retourner la valeur de l’objet de type Boolean il va en fait réaliser un unboxing d’une valeur primitive. Or, le type primitif boolean ne possède que deux valeurs possibles avec false en valeur par défaut. Ainsi, si on ne force pas la valeur de retour avec thenReturn(), cet unboxing va retourner la valeur du type primitif boolean plutôt que la valeur par défaut de la classe Boolean. Il faut donc faire attention à bien compléter tous les tests pour éviter des régressions dans les tests. Il faut noter que ceci fonctionne avec toutes les classes correspondantes aux types primitifs (Boolean, Integer…).

spacer

Laisser un commentaire