web-dev-qa-db-fra.com

Comment utiliser ArgumentCaptor pour le stubbing?

Dans Mockito documentation et javadocs il est dit

Il est recommandé d'utiliser ArgumentCaptor avec vérification mais pas avec stubbing.

mais je ne comprends pas comment ArgumentCaptor peut être utilisé pour le stubbing. Quelqu'un peut-il expliquer la déclaration ci-dessus et montrer comment ArgumentCaptor peut être utilisé pour créer un talon ou fournir un lien indiquant comment procéder?

152
Can't Tell

En supposant que la méthode suivante soit testée:

public boolean doSomething(SomeClass arg);

La documentation de Mockito indique que vous devriez pas utiliser le capteur de cette manière:

when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);
assertThat(argumentCaptor.getValue(), equalTo(expected));

Parce que vous pouvez simplement utiliser Matcher pendant le stubbing:

when(someObject.doSomething(eq(expected))).thenReturn(true);

Mais la vérification est une histoire différente. Si votre test doit s'assurer que cette méthode a été appelée avec un argument spécifique, utilisez ArgumentCaptor et voici le cas pour lequel elle est conçue:

ArgumentCaptor<SomeClass> argumentCaptor = ArgumentCaptor.forClass(SomeClass.class);
verify(someObject).doSomething(argumentCaptor.capture());
assertThat(argumentCaptor.getValue(), equalTo(expected));
261
Rorick

La ligne

when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);

ferait la même chose que

when(someObject.doSomething(Matchers.any())).thenReturn(true);

Donc, en utilisant argumentCaptor.capture () quand stubbing n'a aucune valeur ajoutée. Utiliser Matchers.any () montre mieux ce qui se passe réellement et est donc meilleur pour la lisibilité. Avec argumentCaptor.capture (), vous ne pouvez pas lire quels arguments sont vraiment appariés. Et au lieu d’utiliser any (), vous pouvez utiliser des corrélateurs plus spécifiques lorsque vous avez plus d’informations (classe de l’argument attendu), afin d’améliorer votre test.

Et un autre problème: si vous utilisez argumentCaptor.capture () lors du stubbing, il est difficile de savoir combien de valeurs vous devriez vous attendre à capturer après la vérification. Nous voulons capturer une valeur lors de la vérification, pas lors de la création de talons car à ce stade, il n'y a pas encore de valeur à capturer. Alors, qu'est-ce que la méthode de capture d'arguments capturés capture lors de la substitution? ou ne capture-t-il rien? Je n'ai pas la réponse à cette question. Je considère que c'est un comportement indéfini et je ne veux pas utiliser un comportement indéfini.

0
Stefan Mondelaers