web-dev-qa-db-fra.com

Utilisation de 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é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());
178
ripper234

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());

Explication

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.


Types primitifs

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.

91
Lii

Cela devrait marcher

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;

verify(bar).DoStuff(any(Foo[].class));
264
jitter

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)

10
thilko

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.

5
Maciej Kowalski