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

Je suis actuellement en train d’utiliser Mockito pour simuler mes objects de couche de service dans une application Spring MVC dans laquelle je souhaite tester mes méthodes Controller. Cependant, comme je l’ai lu sur les spécificités de Mockito, j’ai trouvé que les méthodes doReturn(...).when(...) sont équivalentes à when(...).thenReturn(...) . Donc, ma question est de savoir 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.

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

Une chose que when/thenReturn vous donne, c’est que doReturn/when ne le fait pas, est la vérification de la valeur que vous retournez, au moment de la compilation. Cependant, je pense que cela n’a presque aucune valeur – si vous ne connaissez pas le type, vous le découvrirez dès que vous exécuterez votre test.

Je recommande fortement d’utiliser uniquement doReturn/when . Il est inutile d’apprendre deux syntaxes quand on le fera.

Vous voudrez peut-être vous référer à ma réponse à Forming Mockito “grammars” – une réponse plus détaillée à une question très proche.

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

  • when(...) thenReturn(...) effectue un appel de méthode réel juste avant que la valeur spécifiée ne soit renvoyée. Donc, si la méthode appelée lance 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 Ssortingng methodToBeTested() { return anotherMethodInClass(); } protected Ssortingng 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"); 

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

Méfiez-vous que Mockito.when (Object) est toujours recommandé pour le stubbing, car il est compatible avec le type d’argument et plus lisible (en particulier lors du remplacement d’appels consécutifs).

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

1. Quand espionner des objects réels 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 est appelée afin que spy.get (0) lève IndexOutOfBoundsException (la liste est encore vide)

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

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

2. Remplacer une exception-stubbing précédente:

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

// Impossible: la méthode d’exception-stubbed foo () est appelée pour que RuntimeException soit lancée. when(mock.foo()).thenReturn("bar");

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

doReturn("bar").when(mock).foo(); Les scénarios ci-dessus montrent un compromis entre la syntaxe élégante de Mockito. Notez que les scénarios sont très rares, cependant. L’espionnage devrait être sporadique et le remplacement des exceptions est très rare. Sans parler du fait qu’en général, le remplacement du stub est une odeur potentielle de code qui indique trop de bourrage.

Cette dernière alternative est utilisée pour les méthodes sur des simulacres qui renvoient un void .

S’il vous plaît jeter un oeil, par exemple, ici: Comment faire pour simuler les méthodes avec mockito

Suite à cette réponse , il y a une autre différence: si vous voulez que votre méthode renvoie des valeurs différentes, par exemple quand il est appelé pour la première fois, la deuxième fois, etc., vous pouvez transmettre des valeurs, par exemple …

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

Donc, il retournera false quand la méthode est appelée dans le même cas de test et ensuite, elle retournera false et enfin true.

“mock” peut simuler un object au lieu de le créer, “spy” peut créer un object réel avec des parameters réels. Lorsque nous effectuons des tests unitaires, nous les utilisons souvent. Mais ‘quand (xxx) .thenReturn (xxx)’ utilisé pour mock et ‘doReturn (xxx) .when (xxx)’ utilisé pour espion.