web-dev-qa-db-fra.com

callbacks mockito et obtention de valeurs d'argument

Je n'ai aucune chance d'obtenir Mockito pour capturer les valeurs d'argument de fonction! Je me moque d'un index de moteur de recherche et au lieu de construire un index, je n'utilise qu'un hachage.

// Fake index for solr
Hashmap<Integer,Document> fakeIndex;

// Add a document 666 to the fakeIndex
SolrIndexReader reader = Mockito.mock(SolrIndexReader.class);

// Give the reader access to the fake index
Mockito.when(reader.document(666)).thenReturn(document(fakeIndex(666))

Je ne peux pas utiliser d'arguments arbitraires car je teste les résultats des requêtes (quels documents elles renvoient). De même, je ne veux pas spécifier de valeur spécifique et avoir une ligne pour chaque document!

Mockito.when(reader.document(0)).thenReturn(document(fakeIndex(0))
Mockito.when(reader.document(1)).thenReturn(document(fakeIndex(1))
....
Mockito.when(reader.document(n)).thenReturn(document(fakeIndex(n))

J'ai consulté la section des rappels de la page tilisation de Mockito . Malheureusement, ce n'est pas Java et je ne pouvais pas obtenir ma propre interprétation de cela pour fonctionner en Java.

EDIT (pour clarification): Comment amener Mockito à capturer un argument X et à le transmettre à ma fonction? Je veux la valeur exacte (ou ref) de X passé à la fonction.

Je ne veux pas énumérer tous les cas, et les arguments arbitraires ne fonctionneront pas car je teste différents résultats pour différentes requêtes.

La page Mockito dit

val mockedList = mock[List[String]]
mockedList.get(anyInt) answers { i => "The parameter is " + i.toString } 

Ce n'est pas Java, et je ne sais pas comment traduire en Java ou transmettre ce qui est arrivé à une fonction.

68
nflacco

Je n'ai jamais utilisé Mockito, mais je veux apprendre, alors voilà. Si quelqu'un répond moins que moi, essayez d'abord sa réponse!

Mockito.when(reader.document(anyInt())).thenAnswer(new Answer() {
 public Object answer(InvocationOnMock invocation) {
     Object[] args = invocation.getArguments();
     Object mock = invocation.getMock();
     return document(fakeIndex((int)(Integer)args[0]));
     }
 });
89
Ed Staub

Découvrez ArgumentCaptors:

http://site.mockito.org/mockito/docs/1.10.19/org/mockito/ArgumentCaptor.html

ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
Mockito.when(reader.document(argument.capture())).thenAnswer(
  new Answer() {
    Object answer(InvocationOnMock invocation) {
      return document(argument.getValue());
    }
  });
49
qualidafial

Vous voudrez peut-être utiliser verify () en combinaison avec ArgumentCaptor pour assurer l'exécution dans le test et ArgumentCaptor pour évaluer les arguments:

ArgumentCaptor<Document> argument = ArgumentCaptor.forClass(Document.class);
verify(reader).document(argument.capture());
assertEquals(*expected value here*, argument.getValue());

La valeur de l'argument est évidemment accessible via argument.getValue () pour une manipulation/vérification ultérieure ou tout ce que vous souhaitez faire.

26
fl0w

Avec Java 8, cela pourrait ressembler à ceci:

Mockito.when(reader.document(anyInt())).thenAnswer(
  (InvocationOnMock invocation) -> document(invocation.getArguments()[0]));

Je suppose que document est une carte.

10