110 votes

Comment fonctionne l'invocation mockito when ()?

Compte tenu de la déclaration suivante de Mockito:

 when(mock.method()).thenReturn(someValue);
 

Comment Mockito crée-t-il un proxy pour une simulation, étant donné que l'instruction mock.method () transmettra la valeur de retour à when ()? J'imagine que cela utilise des éléments CGLib, mais j'aimerais savoir comment cela se fait techniquement.

112voto

Paul Morie Points 6956

La réponse courte est que dans votre exemple, le résultat d' mock.method() va être d'un type approprié valeur vide; mockito utilise indirection via l'utilisation de proxy, la méthode d'interception, et une instance partagée de l' MockingProgress de la classe afin de déterminer si une invocation d'une méthode sur un objet fantaisie pour cogner ou de relecture d'un écrasé le comportement plutôt que sur la transmission de l'information au sujet de buter par la valeur de retour d'une moqué de méthode.

Une mini-analyse dans un couple de minutes à regarder la mockito code est comme suit. Remarque, c'est un très approximative de la description il y a beaucoup de détails dans le jeu ici. Je vous suggère de consulter la source sur github vous-même.

Tout d'abord, lorsque vous vous moquez d'une classe à l'aide de l' mock méthode de Mockito classe, c'est essentiellement ce qui se passe:

  1. Mockito.mock délégués org.mockito.internal.MockitoCore.fantaisie, en passant par défaut se moquer de paramètres en tant que paramètre.
  2. MockitoCore.mock délégués org.mockito.internal.util.MockUtil.createMock
  3. L' MockUtil classe utilise l' ClassPathLoader classe pour obtenir une instance de l' MockMaker à utiliser pour créer la maquette. Par défaut, le CgLibMockMaker classe est utilisée.
  4. CgLibMockMaker utilise une classe emprunté JMock, ClassImposterizer qui traite de la création de la maquette. Les éléments clés de la "mockito magique" utilisés sont l' MethodInterceptor utilisé pour créer la maquette: le mockito MethodInterceptorFilter, et une chaîne de MockHandler les instances, y compris une instance de MockHandlerImpl. La méthode de l'intercepteur passe invocations à MockHandlerImpl exemple, qui met en œuvre la logique d'entreprise qui doivent être appliquées lorsqu'une méthode est appelée sur une maquette (c'est à dire, cherchant à voir si une réponse est enregistrée déjà, afin de déterminer si l'invocation représente un nouveau tampon, etc. L'état par défaut, c'est que si un talon n'est pas déjà inscrits pour la méthode invoquée, un type approprié vide , la valeur renvoyée.

Maintenant, regardons le code dans votre exemple:

when(mock.method()).thenReturn(someValue)

Voici l'ordre que ce code s'exécute dans:

  1. mock.method()
  2. when(<result of step 1>)
  3. <result of step 2>.thenReturn

La clé pour comprendre ce qui se passe, c'est ce qui se passe lorsque la méthode de la maquette est invoquée: la méthode de l'intercepteur est passé de l'information sur l'invocation de la méthode, et les délégués à la chaîne d' MockHandler des cas, ce qui a finalement délégué MockHandlerImpl#handle. Au cours MockHandlerImpl#handle, les modèles de gestionnaire d'crée une instance de OngoingStubbingImpl et passe à l'partagé MockingProgress de l'instance.

Lorsque l' when méthode est appelée après l'invocation de l' method(), il délègue à d' MockitoCore.when, qui appelle l' stub() méthode de la même classe. Cette méthode présente les cours buter par le partage de l' MockingProgress de l'instance qui le raillaient method() invocation a écrit dans, et le renvoie. Ensuite, thenReturn méthode est appelée sur l' OngoingStubbing de l'instance.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X