web-dev-qa-db-fra.com

méthodes simulées dans la même classe

J'utilise Mockito pour me moquer d'une méthode de la même classe pour laquelle j'écris un test. J'ai vu d'autres réponses sur SO ( Méthode moqueuse de la même classe ), mais je les ai probablement mal comprises, car je rencontre des problèmes.

 class Temp() {

    public boolean methodA(String param) {

         try {

             if(methodB(param))
                   return true;

             return false;
         } catch (Exception e) {
               e.printStackTrace();
         }
    }
 }

Ma méthode de test:

 @Test
 public void testMethodA() {

    Temp temp = new Temp();
    Temp spyTemp = Mockito.spy(temp);

    Mockito.doReturn(true).when(spyTemp).methodB(Mockito.any()); 
    boolean status = temp.methodA("XYZ");

    Assert.assertEquals(true, status);
 }

Cependant, je fais imprimer l'impression parce que la définition de methodB est exécutée ..__ Je crois comprendre que la définition de methodB serait simulée en utilisant spyTemp. Cependant, cela ne semble pas être le cas.

Quelqu'un peut-il s'il vous plaît expliquer où je vais mal?

9
learningMyWayThru

Le premier problème est que vous devez utiliser un objet spyTest pour attendre quelque chose de Mockito. Ici ce n'est pas la même chose que test. spyTemp est un objet enveloppé par Mockito temp

Un autre problème est que vous ne bloquez que methodB(), mais essayez d’exécuter methodA(). Oui, dans votre implémentation de methodA(), vous appelez methodB (), mais vous appelez à this.methodB(), pas en tant que spyTemp.methodB(). Ici, vous devez comprendre que moqueur ne fonctionnerait que si vous l'appeliez sur l'instance de temp. Il est enveloppé par un proxy Mockito qui intercepte votre appel et si vous avez annulé une méthode, il appellera votre nouvelle implémentation au lieu de l’originale. Mais depuis l'appel de la méthode d'origine, vous ne savez rien du proxy Mockito. Donc, votre méthode "overriden" serait appelée uniquement lorsque vous exécutez spyTemp.methodB()

Cela devrait fonctionner:

Mockito.doReturn(true).when(spyTemp).methodB(Mockito.any()); 
boolean status = spyTemp.methodB("XYZ");
11
Konstantin Labun

Vous avez créé un espion et vous vous êtes moqué de methodB(). C'est correct! Mais vous avez appelé methodA() sur l'objet d'origine. Pour obtenir le résultat correct, appelez-le sur l'espion

boolean status = spyTemp.methodA("XYZ");
4
CoronA

Notez les éléments suivants de la documentation Mockito:

Mockito ne pas déléguer des appels à l'instance réelle transmise, à la place il en crée une copie. Donc, si vous gardez l'instance réelle et interagissez avec elle, ne vous attendez pas à ce que l'espionné en soit conscient. interaction et leur effet sur l'état de l'instance réelle. Le corollaire est que lorsque la méthode unubarbed est appelée sur l'espion mais pas sur le. instance réelle , vous ne verrez aucun effet sur l'instance réelle.

Cela fait spécifiquement référence à votre situation. Vous conservez une référence à temp, puis appelez sa methodA. Mockito n'épie pas du tout cette instance. il espionne spyTemp. Donc, la methodB normale est appelée.

Notez que vous devriez éviter complètement les simulacres partiels pour le nouveau code.

2
sprinter