Mockito Injecter de la maquette en Spy objet
Je suis en train d'écrire un scénario de test pour une Classe qui a un niveau 2 de l'injection de dépendance. J'utilise @Spy annotation du 1 au niveau de l'injection de dépendances de l'objet, et je voudrais, à se Moquer de la 2ème niveau de l'injection. Cependant, j'ai continué à obtenir null pointer exception sur le 2ème niveau. Est-il possible que j'injecte de la fantaisie dans le @Spy objet?
public class CarTestCase{
@Mock
private Configuration configuration;
@Spy
private Engine engine;
@InjectMocks
private Car car;
@Test
public void test(){
Mockito.when(configuration.getProperties("")).return("Something");
car.drive();
}
}
public class Car{
@Inject
private Engine engine;
public void drive(){
engine.start();
}
}
public class Engine{
@Inject
private Configuration configuration;
public void start(){
configuration.getProperties(); //null pointer exception
}
}
avez-vous initialisé se moque avec
non, mais quel est le rapport à cette question?
bien que le fait de Mockito faire ce qu'il est censé faire avec les objets annotés
J'ai essayé de mettre le MockitoAnnotations.initmocks(ce) au début de la fonction de test, mais ça ne fonctionne toujours pas
Avez-vous aussi essayer l'annotation Moteur avec @InjectMocks?
MockitoAnnotations.initmocks(this)
non, mais quel est le rapport à cette question?
bien que le fait de Mockito faire ce qu'il est censé faire avec les objets annotés
@Spy
, @Mock
, @InjectMocks
etc donc, si vous faites cela après la construction de car
se moque doit être injecté....J'ai essayé de mettre le MockitoAnnotations.initmocks(ce) au début de la fonction de test, mais ça ne fonctionne toujours pas
Avez-vous aussi essayer l'annotation Moteur avec @InjectMocks?
OriginalL'auteur Wildchild | 2017-05-11
Vous devez vous connecter pour publier un commentaire.
Mockito ne peut pas effectuer une telle délicat injections que ce n'est pas une injection de cadre. Donc, vous avez besoin de revoir votre code afin de le rendre plus testable. C'est facile à faire en utilisant le constructeur de l'injection:
Dans ce cas, vous devez supporter les moqueries et l'injection manuellement:
fonctionne de la même façon. Vous n'avez pas à appeler le constructeur explicitement, le Printemps va le faire pour vous si vous êtes dans le Ressort du contexte. En outre, le champ d'injection n'est pas recommandé, il est toujours préférable d'utiliser le constructeur de l'injection.
OriginalL'auteur Sergii Bishyr
J'ai vagabondé comment injecter une maquette dans un spy.
L'approche suivante sera pas travail:
Mais le comportement désiré peut être réalisé par un "hybride", lors de l'utilisation à la fois l'annotation manuelle et de moqueries. Le suivant fonctionne parfaitement:
(
SubjectUnderTest
ici dépend deMySpy
, etMySpy
à son tour dépend deNeedToBeMocked
).UPD: Personnellement, je pense que si vous avez à faire une telle magie, trop souvent, il pourrait être un signe qu'il ya quelque chose de mal avec dependenicies entre vos classes et il vaut la peine d'effectuer un peu de refactoring pour améliorer votre code.
Pour être clair, cela fonctionne, mais il semble fonctionner par "magie". Je suis heureux de l'utiliser pour résoudre mon court terme le problème (et upvoted), mais j'ai le sentiment de malaise que cela pourrait briser à tout moment 🙂
oui, cette approche peut probablement pause dans les futures versions de Mockito si ils vont changer la manière dont ils créent des simulacres et des espions. Pour voir comment cela fonctionne pour le moment, vous pouvez vous arrêter à un débogueur point d'arrêt à l'intérieur d'un
@Test
méthode et regardez ce qui se trouve à l'intérieur d'unmySpy
variable. Il est une instance deMySpy
objet une modification des méthodes qui ne leur stuff supplémentaire, et ensuite appeler les méthodes originales. Tous les champs sont toujours là et peut être injecté par@InjectMocks
.OriginalL'auteur Yoory N.
J'ai également rencontré ce problème au cours de l'unité de test avec Spring boot, mais j'ai trouvé une solution pour l'utilisation de deux @Spy et @InjectMocks
Réponse précédente à partir de Yoory N.
Parce que InjectMocks besoin d'avoir instance créée, de sorte que la solution fonctionne pour moi est au-dessous,
NotAMockException
l'aide de la version 2.21.0 de Mockito. Sur un autre projet avec l'ancien Mockito 1.10.19 cela fonctionne pas comme prévu -- les dépendances sont injectés, mais lespy
champ n'est pas un vrai espion et je ne peux pas faire des choses commeMockito.verify(mySpy).someMethodCall();
.OriginalL'auteur Jack Yang
Je pense que je viens de trouver la réponse définitive. J'ai essayé Yoory approche, mais il a changé l'ordre des annotations :
Je suppose que Mockito crée d'abord la maquette, et ajoute un espion sur le dessus de cela. Donc, il n'est pas nécessaire d'instancier la MySpy objet.
spy
est un véritable Mockito d'espionnage et de tous les champs sont injectés. Mais maintenant, il ne parvient pas à injecter de l'espionnage dansSubjectUnderTest
instance à l'aide de@InjectMocks
(comme dans mon exemple) et je reçois un NullPointerException quand il essaie de spy appel de méthodes. Testé sur Mockito 2.21.0. N'avons pas encore d'idée sur la manière de remédier à cela.OriginalL'auteur DavidBu