Utiliser la méthode générique “any ()” de Mockito

J’ai une interface avec une méthode qui attend un tableau de Foo :

 public interface IBar { void doStuff(Foo[] arr); } 

Je me moque de cette interface en utilisant Mockito, et je voudrais affirmer que doStuff() est appelé, mais je ne veux pas valider quel argument est passé – “ça m’est égal”.

Comment puis-je écrire le code suivant en utilisant any() , la méthode générique, au lieu de anyObject() ?

 IBar bar = mock(IBar.class); ... verify(bar).doStuff((Foo[]) anyObject()); 

Depuis Java 8, vous pouvez utiliser la méthode argument-less any et l’argument type sera déduit par le compilateur:

 verify(bar).doStuff(any()); 

Explication

La nouveauté de Java 8 est que le type cible d’une expression sera utilisé pour déduire des parameters de type de ses sous-expressions. Avant Java 8, seuls les arguments aux méthodes étaient utilisés pour l’inférence des parameters de type (la plupart du temps).

Dans ce cas, le type de paramètre de doStuff sera le type cible de any() , et le type de valeur de retour de any() sera choisi pour correspondre à ce type d’argument.


Types primitifs

Cela ne fonctionne pas avec les types primitifs, malheureusement:

 public interface IBar { void doPrimitiveStuff(int i); } verify(bar).doPrimitiveStuff(any()); // Comstacks but throws NullPointerException verify(bar).doPrimitiveStuff(anyInt()); // This is what you have to do instead 

Le problème est que le compilateur déduira Integer comme valeur de retour de any() . Mockito ne sera pas au courant (à cause de l’effacement de type) et retournera la valeur par défaut pour les types de référence, qui est null . Le moteur d’exécution essaiera de désencapsuler la valeur de retour en appelant la méthode intValue dessus avant de la transmettre à doStuff , et l’exception sera lancée.

Cela devrait fonctionner

 import static org.mockito.Matchers.any; import static org.mockito.Mockito.verify; verify(bar).DoStuff(any(Foo[].class)); 

Vous pouvez utiliser Mockito.isA() pour cela:

 import static org.mockito.Matchers.isA; import static org.mockito.Mockito.verify; verify(bar).doStuff(isA(Foo[].class)); 

http://site.mockito.org/mockito/docs/current/org/mockito/Matchers.html#isA(java.lang.Class)

Comme je devais utiliser cette fonctionnalité pour mon dernier projet (à un moment donné, nous avons mis à jour depuis la version 1.10.19), juste pour garder les utilisateurs (qui utilisent déjà la version 2.1.0 ou supérieure de mockito-core ) à jour, le statique les méthodes des réponses ci-dessus doivent être sockets dans la classe ArgumentMatchers :

 import static org.mockito.ArgumentMatchers.isA; import static org.mockito.ArgumentMatchers.any; 

Gardez cela à l’esprit si vous prévoyez de garder vos artefacts de mockito à jour, à partir de la version 3, cette classe pourrait ne plus exister:

Conformément à 2.1.0 et ci-dessus, javadoc de org.mockito.Matchers déclare:

Utilisez org.mockito.ArgumentMatchers . Cette classe est maintenant obsolète afin d’éviter un conflit de noms avec la classe Hamcrest * org.hamcrest.Matchers . Cette classe sera probablement supprimée dans la version 3.0.