web-dev-qa-db-fra.com

Mockito - différence entre doReturn () et when ()

Je suis actuellement en train d'utiliser Mockito pour simuler mes objets de couche de service dans une application Spring MVC dans laquelle je souhaite tester mes méthodes de contrôleur. Cependant, comme je l'ai lu sur les spécificités de Mockito, j'ai constaté que les méthodes doReturn(...).when(...) sont équivalentes à when(...).thenReturn(...). Donc, ma question est la suivante: quel est l’intérêt d’avoir deux méthodes qui font la même chose ou quelle est la différence subtile entre doReturn(...).when(...) et when(...).thenReturn(...)?

Toute aide serait appréciée.

157
blackpanther

Les deux syntaxes de stubbing sont à peu près équivalentes. Cependant, vous pouvez toujours utiliser doReturn/when pour le stubbing; mais il y a des cas où vous ne pouvez pas utiliser when/thenReturn. La substitution de méthodes void en est une. D'autres incluent l'utilisation avec des espions Mockito, et écrasant la même méthode plus d'une fois.

Une chose que when/thenReturn vous donne, mais que doReturn/when ne fait pas, est la vérification du type de la valeur que vous retournez au moment de la compilation. Cependant, je pense que cela n'a presque aucune valeur - si vous vous trompez de type, vous le saurez dès que vous exécutez votre test.

Je recommande fortement d'utiliser uniquement doReturn/when. Il ne sert à rien d'apprendre deux syntaxes quand on le fera.

Vous voudrez peut-être vous référer à ma réponse sous formant des "grammaires" de Mockito - une réponse plus détaillée à une question très étroitement liée.

189
Dawood ibn Kareem

Les deux approches se comportent différemment si vous utilisez un objet espionné (annoté avec @Spy) au lieu d'un faux (annoté avec @Mock):

  • when(...) thenReturn(...)effectue un appel de méthode réel juste avant que la valeur spécifiée soit renvoyée. Donc si la méthode appelée lève une exception, vous devez la gérer/la simuler, etc. Bien sûr, vous obtenez toujours votre résultat (ce que vous définissez dans thenReturn(...))

  • doReturn(...) when(...)n'appelle pas du tout la méthode.

Exemple:

public class MyClass {
     protected String methodToBeTested() {
           return anotherMethodInClass();
     }

     protected String anotherMethodInClass() {
          throw new NullPointerException();
     }
}

Tester:

@Spy
private MyClass myClass;

// ...

// would work fine
doReturn("test").when(myClass).anotherMethodInClass();

// would throw a NullPointerException
when(myClass.anotherMethodInClass()).thenReturn("test");
165
akcasoy

Le fichier javadoc de Mockito semble indiquer pourquoi utiliser doReturn() au lieu de when(). Utilisez doReturn () dans les rares cas où vous ne pouvez pas utiliser Mockito.when (Object).

Notez que Mockito.when (Object) est toujours recommandé pour le talonnage car il est compatible avec les types d'arguments et plus lisible (en particulier lors du raccrochage d'appels consécutifs).

Voici les rares occasions où doReturn () est pratique:

1. Quand espionner de vrais objets et appeler de vraies méthodes sur un espion apporte des effets secondaires

List list = new LinkedList(); List spy = spy(list);

// Impossible: la méthode réelle s'appelle alors spy.get (0) lève une exception IndexOutOfBoundsException (la liste est encore vide)

when(spy.get(0)).thenReturn("foo");

// Vous devez utiliser doReturn () pour le stubbing: doReturn("foo").when(spy).get(0);

2. Remplacement d'un précédent stubbing d'exception:

when(mock.foo()).thenThrow(new RuntimeException());

// Impossible: la méthode foo () comportant une exception est appelée ainsi, une exception RuntimeException est levée. when(mock.foo()).thenReturn("bar");

// Vous devez utiliser doReturn () pour le stubbing:

doReturn("bar").when(mock).foo(); Les scénarios ci-dessus indiquent un compromis entre la syntaxe élégante de Mockito. Notez que les scénarios sont très rares, cependant. L'espionnage doit être sporadique et il est très rare que la dérogation d'exception soit utilisée. Sans oublier qu'en général, le remplacement génial est une odeur potentielle de code signalant un comportement excessif.

9
user2493028

Cette dernière alternative est utilisée pour les méthodes sur des copies qui retournent void.

Jetez un coup d'œil, par exemple, ici: Comment se moquer des méthodes avec mockito

5
vikingsteve

Continueuing this answer , Il existe une autre différence: si vous souhaitez que votre méthode renvoie des valeurs différentes, par exemple lorsqu’elle est appelée pour la première fois, une seconde fois, etc., vous pouvez alors transmettre des valeurs, par exemple ...

PowerMockito.doReturn(false, false, true).when(SomeClass.class, "SomeMethod", Matchers.any(SomeClass.class));

Donc, il retournera false lorsque la méthode sera appelée dans le même cas de test, puis retournera false encore et finalement true.

5
AZ_