11
votes

Utilisation de JMOCKIT pour moquer des implémentations d'interface autofiitées

Nous écrivons des tests junivers pour une classe qui utilise la mise en forme de ressort pour injecter une dépendance qui est une instance d'une interface. Puisque la classe sous test n'a jamais explicit explicitement instanciable la dépendance ou la dépendance est passée dans un constructeur, il semble que JMockit ne se sent pas obligé de l'instancier non plus.

Jusqu'à présent, nous utilisons SpringRunner pour avoir des dépendances simulées de printemps. nous, ce qui fonctionne. Deux choses que nous n'aimons pas à propos de cela sont 1) Le cadre de printemps doit être chargé et initialisé à chaque fois en exécutant les tests qui ne sont pas exactement rapides, et 2) nous sommes obligés de créer explicitement toutes les dépendances simulées en tant que vraies classes, quelque chose qui JMockit aide à éliminer. P>

Voici un exemple simplifié de ce que nous testons: P>

public class UnitUnderTest {

   @Autowired
   ISomeInterface someInterface;

   public void callInterfaceMethod() {

      System.out.println( "UnitUnderTest.callInterfaceMethod calling someInterface.doSomething");
      someInterface.doSomething();
   }

}


5 Réponses :


8
votes

2 commentaires

Ceci est une classe utile pour être sûr. Néanmoins, devoir créer explicitement le motif défaite l'une des principales raisons d'utiliser JMockit en premier lieu.


C'est super utile. Je crée des simulacres à la main et j'ai eu une propriété autonome dans la classe testée. Cela m'a permis de définir la propriété dans le test sur la simulation sans modifier le code sous test! Excellent.



12
votes

JMockit instancera toujours une interface moquée (sauf dans le cas d'un dernier champ simulé), mais cela ne se produit que dans le code de test. Il n'injectera pas automatiquement l'instance dans le code sous test.

Vous devrez injecter manuellement l'instance moquée. Par exemple: xxx

maquette.decapsulation est une classe d'utilités basée sur une réflexion qui vous permet d'invoquer des méthodes privées, d'obtenir / définir des champs, etc. < / p>


5 commentaires

Juste une note: puisque cette réponse a été postée, JMockit a ajouté une assistance supplémentaire pour une injection automatique d'objets simulés dans des classes testées. Dans cet exemple, remplacer @autowired avec @TEST et @mocké avec @Ijecttable .


WOW @ ROGÉRIOO! c'est bien! Jmockit est si puissant ... je l'aime !!


@ Rogério Can JMockit Tool de couverture générer un rapport sur Mockito? Notre code de test hérité est avec Mockito. Tous les liens sont utiles.


@ Yuyue007 Oui, l'outil de couverture ne nécessite pas la présence de JMockit.jar, bien que ce soit plus facile quand il est présent. Vous auriez besoin d'utiliser le paramètre "-JavaAgent: jvm d'initialisation JVM (à partir de la ligne de commande / IDE ou du script de construction des fourmis / maven / gradlet). Destais dans le page de documentation .


@ Rogério cool! Je rencontre un problème lorsque vous utilisez Cascade Mock avec type générique, j'ai créé un problème dans GitHub, pourriez-vous aider à vérifier où je suis faux, ou si c'est un bug. Merci beaucoup.



4
votes

Avec les astuces gentiment fournies ci-dessus, voici ce que j'ai trouvé le plus utile comme une personne jolie nouvelle à JMockit: JMockit fournit la classe code> désencapsulation code> pour vous permettre de définir les valeurs des champs dépendants privés (pas besoin de Faites glisser les bibliothèques de ressort) et la classe Maquette code> qui vous permet de créer explicitement une implémentation d'une interface et de simulacter une ou plusieurs méthodes de l'interface. Voici comment j'ai fini par résoudre ce cas particulier:

@Before
public void setUp() {

   IMarketMakerDal theMock = new MockUp <IMarketMakerDal>() {

      @Mock
      MarketMakerDcl findByMarketMakerGuid( String marketMakerGuid ) {

         MarketMakerDcl marketMakerDcl = new MarketMakerDcl();
         marketMakerDcl.setBaseCurrencyCode( CURRENCY_CODE_US_DOLLAR );
         return marketMakerDcl;
      }
   }.getMockInstance();

   setField( unitUnderTest, theMock );
}


0 commentaires

3
votes

Pour les personnes qui ont rencontré xxx

ou xxx

erreur lors de l'utilisation jmockit pour simuler @autowired champ dans ressort (ou démarrage de ressort ), j'ai fait en dessous de deux étapes pour éviter les erreurs ci-dessus:

  1. Utilisez @ Tetseté (entièrement sous -ilialisé = true) au lieu de @TEST

    https://groups.google.com / Forum / #! Msg / JMockit-Utilisateurs / UO0SS51LSX24 / LQHLNN - EJCJ

    1. revenir à la version de JMockit vers JMockit vers 1.18 ou précédent

      https://groups.google.com/forum/#! Sujet / JMOCKIT-Utilisateurs / WMFZGGSA8LM


0 commentaires

1
votes

Si vous avez une annotation @qualifier pour l'interface, vous devez nommer votre champ @Ijectable exactement tel qu'il est nommé en qualificatif.

Voici de citation de JMOCKIT DOC : P>

noms personnalisés spécifiés dans les annotations de champs à partir de Java EE (@Resource (nom), @Named) ou la structure de ressort (@qualifier) ​​sont utilisés lors de la recherche d'une valeur correspondante @Ijejetable ou @TEST. Lorsqu'un tel nom contient A - (DASH) ou. caractère (point), le nom de la camélie correspondante est utilisé à la place. P> blockquote>

Par exemple: P>

public class AClassTest {

   @Injectable
   private Bean1 bean1;

   @Injectable
   private AmqpTemplate myDashedName;

   @Tested
   private AClass aClass = new AClass();
}


0 commentaires