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ée, mais je ne veux pas valider les arguments qui ont été passés - "ça ne fait rien".
Comment é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 sans argument any
et l'argument de type sera déduit par le compilateur:
verify(bar).doStuff(any());
La nouvelle chose dans Java 8 est que le type de cible d'une expression sera utilisé pour déduire les paramètres de type de ses sous-expressions. Avant Java 8, seuls les arguments des méthodes étaient utilisés pour l'inférence de paramètre 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.
Cela ne fonctionne pas avec les types primitifs, malheureusement:
public interface IBar {
void doPrimitiveStuff(int i);
}
verify(bar).doPrimitiveStuff(any()); // Compiles 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
en tant que valeur de retour de any()
. Mockito n'en sera pas conscient (en raison de l'effacement du 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écompresser la valeur renvoyée en appelant la méthode intValue
avant de la transmettre à doStuff
, et l'exception sera levée.
Cela devrait marcher
import static org.mockito.ArgumentMatchers.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 la version 1.10.19), il suffit de garder les utilisateurs (qui utilisent déjà le mockito-core version 2.1.0 ou supérieure ) à jour, les méthodes statiques des réponses ci-dessus doivent être prises de la classe ArgumentMatchers
:
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.any;
Veuillez garder ceci à l’esprit si vous prévoyez de garder vos artefacts mockito à jour, car à partir de la version 3, cette classe n’existera peut-être plus:
En 2.1.0 et ci-dessus, le javadoc de org.mockito.Matchers indique:
Utilisez
org.mockito.ArgumentMatchers
. Cette classe est maintenant obsolète afin d'éviter une collision de noms avec Hamcrest *org.hamcrest.Matchers
class. Cette classe sera probablement supprimée dans la version 3.0.