Comparaison entre Mockito vs JMockit - pourquoi est-Mockito voté mieux que JMockit? [fermé]
-
29-09-2019 - |
Question
J'enquête sur quel cadre moqueur à utiliser pour mon projet et ont réduit à JMockit et Mockito .
Je remarque que Mockito a été voté « la meilleur cadre de simulation pour Java » sur Stackoverflow.
En comparant les caractéristiques sur JMockit de « Mocking outil Matrice comparision » il semble que JMockit a plusieurs caractéristiques différentes.
quelqu'un ne dispose d'aucune information spécifique (pas d'opinions) sur ce que Mockito peut faire qui ne peut être réalisé avec JMockit et vice versa?
La solution
Mise à jour septembre 2019: Le seul cadre moquaient pris en charge (par défaut) par Spring Boot est Mockito . Si vous utilisez Spring, la réponse est tout à fait évidente.
Je dirais que la concurrence est entre JMockit et PowerMock , puis Mockito .
Je partirais jMock et EasyMock « plaine » parce qu'ils utilisent uniquement proxy et CGLIB et ne pas utiliser l'instrumentation Java 5 comme les cadres les plus récents.
jMock aussi n'a pas une version stable depuis plus de 4 ans. jMock 2.6.0 requis 2 ans pour passer de RC1 à RC2, puis encore 2 ans avant effectivement est sorti.
En ce qui concerne Proxy & CGLIB vs Instrumentation:
(EasyMock et jMock) sont basés sur java.lang.reflect.Proxy, qui nécessite une interface être mis en œuvre. De plus, ils soutenir la création d'objets fantaisie pour les classes par le biais de la sous-classe CGLIB génération. À cause de cela, a déclaré les classes ne peuvent pas être définitives et ne les méthodes d'instance Overridable peuvent être moqué. Plus important encore, cependant, lors de l'utilisation de ces outils les dépendances de code en cours de test (qui est, les objets d'autres classes sur qui une classe donnée à l'essai depends) doit être contrôlée par le des tests, de sorte que les cas peuvent être simulés transmis aux clients de ceux dépendances. Par conséquent, les dépendances ne peut pas simplement être instancié avec le nouvel opérateur dans une classe de client que nous voulons des tests unitaires d'écriture.
En fin de compte, les limitations techniques des outils conventionnels moqueurs imposer les restrictions de conception suivantes Code de production:
- Chaque classe qui peut avoir besoin d'être moqué dans un test doit soit mettre en œuvre une interface séparée ou non définitive.
- Les dépendances de chaque classe à tester soit doit être obtenue par la création de l'instance configurable méthodes (usines ou d'un service Locator), ou d'être exposé pour la dépendance injection. Dans le cas contraire, les tests unitaires ne seront pas être en mesure de passer des implémentations de maquettes des dépendances à l'unité sous test.
- Comme on ne se moque que des méthodes d'instance, les cours d'être testé unitairement ne peut pas appeler des méthodes statiques leurs dépendances, ni instancier les utiliser l'un des constructeurs.
Le ci-dessus est copié à partir de http://jmockit.org/about.html . En outre, il compare entre lui-même (JMockit), PowerMock et Mockito de plusieurs façons:
Il y a maintenant d'autres outils moqueurs pour Java qui surmontent aussi limites des conventionnels, entre les PowerMock, jEasyTest et MockInject. Celui qui se rapproche le plus à l'ensemble des fonctionnalités de JMockit est PowerMock, donc je vais évaluer brièvement ici (d'ailleurs, les deux autres sont plus limité et ne semblent pas être activement développé plus).
JMockit vs PowerMock
- Tout d'abord, PowerMock ne fournit pas une API complète pour se moquant, mais fonctionne plutôt comme une extension un autre outil, qui peut actuellement être EasyMock ou Mockito. Ceci est évidemment un avantage pour les utilisateurs existants de ces outils.
- JMockit, d'autre part, fournit des API entièrement nouvelles, bien que son API principale (attentes) est similaire à la fois EasyMock et jMock. Alors que ce crée une courbe d'apprentissage plus, il permet également de fournir un JMockit plus simple, plus cohérente et plus facile API d'utilisation.
- Par rapport à l'JMockit API attentes, l'API est PowerMock plus « bas niveau », obligeant les utilisateurs à déterminer et préciser quelles sont les classes besoin d'être préparé pour les tests (avec le @PrepareForTest ({ClassA.class,...}) annotation) et nécessitant appels API spécifiques à traiter différents types de constructions linguistiques qui peuvent être présents dans la production Code: méthodes statiques (MockStatic (ClassA.class)), constructeurs (Suppress (constructeur (ClassXyz.class))), constructeur invocations (ExpectNew (AClass.class)), partielle mocks (createPartialMock (ClassX.class, "MethodToMock")), etc.
- Avec les attentes JMockit, toutes sortes de méthodes et les constructeurs sont moqué d'une manière purement déclarative, avec spécifié moqueur partielle par expressions régulières dans le @Mocked annotation ou simplement « non-moqueur » les membres sans enregistrement attentes; c'est le développeur déclare simplement un peu partagé « mock champs » pour la classe de test, ou certains « Champs simulacres locaux » et / ou « mock paramètres » pour le test individuel méthodes (et dans ce dernier cas, la annotation @Mocked ne sera souvent pas nécessaire).
- Certaines capacités disponibles dans JMockit, telles que le soutien moqueur égaux et hashCode, surchargée les méthodes et les autres, ne sont pas encore pris en charge dans PowerMock. Il y a aussi pas d'équivalent à la capacité de JMockit à cas de capture et maquette implémentations de base spécifiée types comme les tests, exécute sans le code de test lui-même avoir toute connaissance de la mise en œuvre effective classes.
- PowerMock utilise des chargeurs de classe personnalisée (généralement une par classe de test) afin de générer des versions modifiées des classes moqué. Une telle utilisation intensive des chargeurs de classes personnalisés peuvent conduire à les conflits avec les bibliothèques tierces, d'où la nécessité d'utiliser parfois @PowerMockIgnore ( "package.to.be.ignored") annotation sur les classes de test.
- Le mécanisme utilisé par JMockit (instrumentation d'exécution à travers une « Java agent ») est plus simple et plus sûr, même si elle ne nécessite le passage d'un paramètre « -javaagent » à la machine virtuelle Java lorsque le développement sur JDK 1.5; sur 1.6+ JDK (Qui peut toujours être utilisé pour développement, même si le déploiement sur un ancienne version) il n'y a pas exigence, étant donné que JMockit peut charge de manière transparente l'agent Java la demande en utilisant l'API Joindre.
Un autre outil moqueur récent est Mockito. Bien qu'il ne tente pas de dépasser les limites de plus outils (JMock, EasyMock), il ne introduire un nouveau style de comportement des tests avec simulacres. JMockit aussi soutient ce style alternatif, via l'API Verifications.
JMockit vs Mockito
- Mockito repose sur des appels explicites à son API afin de code distinct entre l'enregistrement (quand (...)) et vérifier (vérifier (...)) phases. Cette signifie que toute invocation d'une maquette objet dans le code de test a également besoin un appel à l'API moqueur. De plus, cela conduira souvent à répétitif quand (...) et verify (mock) ... appels.
- Avec JMockit, il existe pas d'appels similaires. Bien sûr, nous avons la nouvelle NonStrictExpectations () et de nouvelles appels constructeur de (Vérifications), mais ils se produisent qu'une seule fois par test (Typiquement), et sont complètement séparer des invocations les méthodes et les constructeurs se moquaient.
- L'API Mockito contient plusieurs incohérences dans la syntaxe utilisée pour invocations aux méthodes moqués. dans le la phase enregistrement, nous avons des appels comme quand (mock.mockedMethod (args)) ... alors que dans la phase vérifier cette même appel sera écrit verify (mock) .mockedMethod (args). Notez que dans le premier cas, le invocation à mockedMethod est faite directement sur l'objet simulé, tandis que dans le second cas, il est mis sur la objet retourné par verify (mock).
- JMockit n'a pas ces contradictions parce que les invocations à méthodes moquaient sont toujours faits directement sur les instances moquaient se. (À une exception près seulement: faire correspondre les invocations sur la même Ainsi raillaient, un onInstance (mock) appel est utilisé, ce qui code comme onInstance (mock) .mockedMethod (args); la plupart des tests ne seront pas besoin d'utiliser, cependant.)
- Tout comme d'autres outils moqueurs qui reposent sur la méthode / emballage, chaining Mockito aussi court dans la syntaxe contradictoire stubbing méthodes vides. Par exemple, vous écrivez lorsque (mockedList.get (1)). thenThrow (new RuntimeException ()); pour un non-vide Procédé et doThrow (nouveau RuntimeException ()) lorsque (mockedList) de .clear (). pour un seul creux. Avec JMockit, il est toujours la même syntaxe: mockedList.clear (); résultat = new RuntimeException ();.
- Une autre incohérence se produit dans l'utilisation des espions Mockito: « se moque » qui permettent aux véritables méthodes à exécuté sur l'instance espionné. Pour Par exemple, si espion fait référence à un vide Liste, puis au lieu d'écrire quand (spy.get (0)). thenReturn ( "foo") vous devra écrire doReturn ( "foo"). quand (espion) .get (0). Avec JMockit, la fonction moqueur dynamique fournit des fonctionnalités similaires à espions, mais sans cette question depuis méthodes réelles sont exécutées uniquement pendant la phase de lecture.
- Dans EasyMock et jMock, les premiers se moquant des API pour Java, l'accent a été entièrement sur l'enregistrement prévu invocations de méthodes fantaisie, par objets fantaisie que (par défaut) ne le font pas permettre à des invocations inattendues. Ceux API permettent également l'enregistrement des invocations autorisées pour les objets fantaisie qui ne permettent invocations inattendues, mais cela a été traité comme une seconde classe fonctionnalité. De plus, avec ces des outils, il n'y a aucun moyen explicitement vérifier les invocations à se moque après la code sous test est exercé. Tous ces vérifications sont effectuées implicitement et automatiquement.
- Dans Mockito (et aussi dans Unitils Mock), le point de vue opposé est pris. Tous les invocations à des objets fantaisie qui peut se produire lors de l'essai, que ce soit enregistré ou non, sont autorisés, jamais attendu. La vérification est effectuée explicitement après le code l'essai est exercé, jamais automatiquement.
- Les deux approches sont trop extrêmes, et par conséquent moins optimale. JMockit attentes et Verifications est la seule API qui permet à la développeur de choisir de façon transparente la meilleure combinaison de stricte (prévu par défaut) et non stricte (autorisée par par défaut) des invocations simulées pour chaque test.
- Pour être plus clair, l'API Mockito a la lacune suivante. Si vous besoin de vérifier que l'appel à une Procédé moqué non nul est passé pendant le test, mais le test nécessite une retourner la valeur de cette méthode qui est différent de la valeur par défaut pour la type de retour, le test Mockito aura le code en double: un lorsque (mock.someMethod ()). thenReturn (xyz) appel à la phase d'enregistrement, et verify (mock) .someMethod () dans la phase de vérification. Avec JMockit, une stricte l'attente peut toujours être enregistré, qui ne doivent être explicitement vérifié. Alternativement, une invocation Nombre de contrainte (temps = 1) peuvent être spécifié pour les non-strict enregistrées attente (avec Mockito tel les contraintes ne peuvent être spécifiées dans un verify (mock, contrainte) appel).
- Mockito a une mauvaise syntaxe des vérifications dans l'ordre, et pour plein vérifications (qui est, en vérifiant que toutes les invocations à des objets fantaisie sont explicitement vérifié). En premier cas, un objet supplémentaire doit être créés, et les appels à VÉRIFIER effectués sur il: afinde afinde = afinde (mock1, mock2, ...). Dans le second cas, les appels comme verifyNoMoreInteractions (mock) ou verifyZeroInteractions (mock1, mock2) besoin d'être.
- Avec JMockit, il vous suffit d'écrire de nouveaux VerificationsInOrder () ou une nouvelle FullVerifications () au lieu de nouvelles Vérifications () (ou une nouvelle FullVerificationsInOrder () pour combiner les deux exigences). Pas besoin de préciser les objets simulés sont impliqués. Non supplémentaires appels API moqueur. Et comme de bonus, en appelant unverifiedInvocations () dans un ordonné bloc de vérification, vous pouvez effectuervérifications relatifs aux commandes qui sont tout simplement impossible dans Mockito.
Enfin, la boîte à outils de test JMockit a une portée plus large et plus ambitieux objectifs que d'autres boîtes à outils moqueurs, en afin de fournir un dossier complet et tests de développeur sophistiqué Solution. Une bonne API pour se moquant, même sans limitations artificielles, n'est pas assez pour la création productive des tests. Un IDE-agnostique, facile à utiliser, et bien outil de couverture de code intégré est également essentiel, et que ce que JMockit couverture vise à fournir. Un autre morceau de l'essai de développeur jeu d'outils qui deviendra plus utile comme la suite de tests croît en taille est la capacité à des tests progressivement ré-exécuter après un changement localisé de production code; cela est également inclus dans le outil de couverture.
(accordée, la source peut être biaisée, mais bien ...)
Je dirais aller avec JMockit . Il est le plus facile à utiliser, flexible et fonctionne pour à peu près tous les cas de ceux et scénarios même difficiles lorsque vous ne pouvez pas contrôler la classe à tester (ou vous ne pouvez pas le casser pour des raisons de compatibilité, etc.).
Mes expériences avec JMockit ont été très positifs.
Autres conseils
Je travaille à la fois avec Mockito et JMockit, et mon expérience avec eux est:
-
Mockito:
- moqueur implicite (-> une meilleure facilité d'utilisation, mais il a le risque de ne pas détecter non autorisés sur les appels de méthode se moque)
- vérification explicite
-
EasyMock:
- explict moqueur
- vérification implicite
-
JMockit:
- supporte à la fois
-
En outre, d'autres avantages de JMockit:
- si vous moquant des méthodes / constructeurs etc statiques (comme l'extension d'une base de code existant très vieux sans UT), vous avez deux choix: 1) Mockito / EasyMock avec l'extension Powermock ou 2) Jmockit
- intégré dans le rapport de couverture
Personnellement, je préfère JMockit, qui je pense est plus riche en fonctionnalités et flexible, mais nécessite une courbe d'apprentissage plus raide petit peu. Il sont généralement plusieurs façons d'atteindre le même effet moqueur, et nécessite plus de soin lors de la conception des simulacres.
J'utilise jMockit uniquement à cause de ses bibliothèques de réflexion dans Deencapsultation.class. J'adore vraiment le style de Mockito, mais je refuse de changer mon code et boueux mon API juste pour un cadre limité test peut nous mettre au travail. Et je suis un fan de tester tout mon code, donc un cadre qui ne peut pas tester facilement des méthodes privées n'est pas ce que je veux utiliser.
je suis influencé par cet article
Après une (grande certes) la courbe d'apprentissage, jMockit est maintenant mon principal cadre de tests unitaires pour se moque.
Pour tester facilement notre codebase héritage (avec beaucoup d'appels de méthodes statiques, etc.), JMockit a été inestimable. [Shameless plug pour une article sur mon blog]
Personnellement, je préfère EasyMock .
La capacité de divert entre Nice, les contrôles moqueurs normal et strictes est l'un sur ma fonction préférée.