Mockito.any () pass Interface avec les génériques


171

est-il possible de passer le type d'une interface avec des génériques?

L'interface:

public interface AsyncCallback<T>

Dans ma méthode de test:

Mockito.any(AsyncCallback.class)

Mettre <ResponseX>derrière ou pour .classn'a pas fonctionné.

Réponses:


306

Il existe un moyen de type sécurisé: utilisez-le ArgumentMatchers.any()et qualifiez-le avec le type:

ArgumentMatchers.<AsyncCallback<ResponseX>>any()

4
Je confirme que cette réponse fonctionne et supprime correctement l'avertissement.
kevinarpe

1
Ce n'est pas vraiment plus sûr car la méthode réelle ne peut être appelée de toute façon qu'avec l'argument correctement typé. Il fallait juste satisfaire le compilateur pré-java8 qui manquait de ce genre d'inférence de type.
herman

J'ai utilisé quelque chose comme ceci ResponseEntity <List <Map <String, Object >>> responseEntity = Matchers. <ResponseEntity <List <Map <String, Object >>>> any (); Et il retourne toujours null
Arun

6
Avec les nouvelles versions de Mockito:(Matchers.<AsyncCallback<ResponseX>>any()
pierrefevrier

15
Matchersest en fait obsolète, mais ArgumentMatchersa fonctionné.
guijob

67

En utilisant Java 8, vous pouvez simplement utiliser any()(en supposant l'importation statique) sans argument ou paramètre de type en raison de l'inférence de type améliorée. Le compilateur sait maintenant à partir du type de cible (le type de l'argument de méthode) que vous entendez réellement Matchers.<AsyncCallback<ResponseX>>any(), qui est la solution pré-Java 8.


Cela ne any()correspondrait pas AsyncCallback<AnyOtherType>aussi?
Matthew Lire

@MatthewRead Using AsyncCallback<AnyOtherType>ne devrait même pas compiler si le type d'argument est 'AsyncCallback <ResponseX>'.
herman

1
Je m'interroge sur une situation où le type d'argument est également générique, mais vous ne voulez que le simuler pour un type concret (ou le simuler pour plusieurs types de différentes manières). Donné when(x.y(any())).thenAnswer(...)par exemple, où yest public <T> T y(AsyncCallback<T> arg). Peut-être serait-il préférable de vérifier le type de réponse, si c'est ce qui est nécessaire?
Matthew a lu

2
@MatthewRead En raison de l'effacement, le type réel ne peut pas être vérifié au moment de l'exécution par Mockito. Donc, vous ne pouvez même pas utiliser isA(). Si l'objet contient un Classobjet correspondant au type et que l'interface l'expose, je suppose que vous pouvez le vérifier dans un matcher personnalisé. Ou par exemple dans le cas d'un Collectionvous pouvez vérifier le type des éléments.
herman

1
Matchersa été remplacé par ArgumentMatchersdans Mockito v2
bheussler

15

J'ai dû adopter le mécanisme suivant pour autoriser les génériques:

import static org.mockito.Matchers.any;
List<String> list = any();
when(callMyMethod.getResult(list)).thenReturn(myResultString);

J'espère que cela aide quelqu'un.


3
Voir ma réponse: ce n'est plus nécessaire avec Java 8.
herman

5

Poster un commentaire de pierrefevrier comme réponse qui pourrait être utile s'il est présent dans une réponse au lieu de commentaires.

Avec les nouvelles versions de Mockito: (Matchers.<AsyncCallback<ResponseX>>any()


1
J'ai ajouté son commentaire à la réponse d'origine
Joergi

2

Suite à la réponse de thSoft, mettre l'appel qualifié à any () dans la méthode signifiait que je pouvais supprimer la qualification puisque le type de retour permettait l'inférence:

private HashMap<String, String> anyStringStringHashMap() {
    return Matchers.any();
}

0

Vous pouvez simplement le lancer, en ajoutant des avertissements de suppression si vous le souhaitez:

@SuppressWarnings("unchecked")    
AsyncCallback<ResponseX> callback = Mockito.any(AsyncCallback.class)

Si Java autorisait les génériques `` génériques '', ils pourraient avoir une méthode comme celle-ci, ce que vous recherchez

private static <T, E> T<E> mock(Class<T<E>> clazz)

Quand j'ai essayé cela, j'ai reçu une erreur dans mon test:You cannot use argument matchers outside of verification or stubbing.
kevinarpe

Ce n'est pas une bonne idée à utiliser @SuppressWarnings: pré-java 8, si vous deviez l'assigner à une variable distincte, vous pourriez simplement l'utiliser any()comme dans la réponse de INtoy. Maintenant, avec java 8, any()peut être utilisé en ligne sans avoir besoin d'une affectation distincte.
herman

@kevinarpe si vous avez plusieurs correspondants d'arguments, ils doivent être appelés dans l'ordre spécifié par le langage Java.
TWiStErRob

0

J'ai eu un problème similaire en utilisant Spring Example:

Mockito.when(repo.findAll(Mockito.<Example<SrvReqToSupplierComment>>any()))
            .thenReturn(Lists.emptyList());

Ici, vous devez utiliser la qualification, la méthode b / c findAll peut prendre plusieurs types, comme Sortet Iterable. Vous pouvez également utiliser Mockito.any(Example.class)bien sûr avec le type d'avertissement de sécurité.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.