Comparaison entre Mockito et JMockit-pourquoi Mockito est-il voté mieux que JMockit? [fermé]

j'enquête sur le cadre de moquerie à utiliser pour mon projet et je l'ai réduit à JMockit et Mockito .

je remarque que Mockito a été élu " la meilleure maquette cadre pour Java " sur Stackoverflow.

En comparant les caractéristiques sur JMockit 's" Moqueur Outil de Comparaison de Matrice " il semble que JMockit présente plusieurs caractéristiques différentes.

quelqu'un a une information spécifique (pas d'avis) sur ce Mockito peut faire qui ne peuvent pas être obtenu avec JMockit et vice-versa?

112
demandé sur Rogério 2010-11-05 14:52:28

5 réponses

je dirais que la compétition est entre JMockit et PowerMock , puis Mockito .

je quitterais" plain " jMock et EasyMock parce qu'ils utilisent seulement proxy & CGLIB et n'utilisent pas D'instrumentation Java 5 comme les cadres plus récents.

jMock n'avait pas non plus de version stable depuis plus de 4 ans. jMock 2.6.0 avait besoin de 2 ans pour passer de RC1 à RC2, puis encore 2 ans avant elle a effectivement été libéré.

Regarding Proxy & CGLIB vs instrumentation:

(EasyMock et jMock) sont basés sur java.lang.refléter.Proxy, ce qui nécessite une interface mettre. En outre, ils soutenir la création d'objets fantaisie pour les classes de la sous-classe CGLIB génération. À cause de cela, dit les classes ne peuvent pas être finales et seulement les méthodes d'instance surridables peuvent être moquer. Plus important encore, cependant, lorsque à l'aide de ces outils de la les dépendances du code en cours d'essai (qui est, les objets des autres classes sur lequel une classe de test dépend) doit être contrôlée par le des essais, afin que les instances simulées puissent être transmis aux clients de ces dépendance. Par conséquent, dépendances ne peut pas simplement être instancié avec le nouvel opérateur dans une classe client pour nous voulons écrire des tests unitaires.

finalement, les limites techniques des outils de moquerie conventionnels imposer les restrictions de conception suivantes: code de production:

  1. chaque classe qui peut avoir besoin d'être moquée dans un essai doit soit mettre en œuvre une interface séparée ou pas définitive.
  2. Les dépendances de chaque classe à tester doit être obtenu par la création d'instance configurable méthodes (usines ou un Service Localisateur), OU être exposé à la dépendance injection. Sinon, les tests unitaires ne seront pas être en mesure de passer se moquer des implémentations des liens de dépendance avec l'unité test.
  3. puisque seules les méthodes d'instance peuvent être moquées, classes à tester à l'unité ne peut pas faire appel à des méthodes statiques leurs dépendances, ni instancier celles-ci par tous les constructeurs.

ci-dessus est copié à partir de http://jmockit.org/about.html . En outre, il compare entre lui-même (Jmockit), PowerMock, et Mockito dans plusieurs façons:

Il ya maintenant d'autres outils de moquerie pour Java qui surmontent également le les limites de l'classiques, entre eux PowerMock, jEasyTest, et MockInject. Celui qui s'en rapproche le plus à L'ensemble des caractéristiques de JMockit est PowerMock, donc je vais évaluer brièvement ici (d'ailleurs, les deux autres sont plus limité et ne semble pas être activement plus développé).

JMockit vs PowerMock

  • tout d'abord, PowerMock ne fournit pas une API complète pour la moquerie, mais au lieu fonctionne comme une extension de un autre outil, qui peut actuellement être EasyMock ou Mockito. C'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. Tout ce crée une courbe d'apprentissage plus longue, il également permet à JMockit de fournir plus simple, plus cohérente et plus facile pour utiliser L'API.
  • comparé à L'API Jmockit Expectations, L'API PowerMock est plus "bas niveau", forçant les utilisateurs à comprendre et spécifier les classes il faut être prêt pour les essais (avec le @PrepareForTest ({ClassA.classe, ...}) annotation) et l'exigence appels API spécifiques à traiter différents types de constructions linguistiques qui peut être présent dans la production code: méthodes statiques (mockStatic (ClassA.classe)), constructeur (supprimer(constructeur(ClassXyz.classe))), invocations des constructeurs (expectNew (AClass.classe)), partielle Mock (createPartialMock (ClassX.classe, "methodToMock")), etc.
  • avec des attentes JMockit, toutes sortes de méthodes et les constructeurs sont moqué d'une manière purement déclarative, avec une moquerie partielle spécifiée par des expressions régulières dans le @Mocked annotation ou simplement "se moquant"" les membres qui n'ont pas enregistré attentes; en effet, le développeur déclare simplement quelques "mock" les champs" pour la classe de test, ou certains "locales se moquer des champs" et/ou "faux paramètres" pour chaque essai les méthodes (et dans ce dernier cas, le @ Moqued annotation souvent ne sera pas nécessaire.)
  • certaines fonctionnalités disponibles dans JMockit, telles que le support pour la moquerie equals et hashCode, substituée méthodes, et d'autres, ne sont actuellement pas pris en charge à PowerMock. Aussi, il est aucun équivalent à la capacité de JMockit saisir les instances et les moqueries mise en œuvre de la base spécifiée types que le test exécute, sans le code d'essai lui-même ayant connaissance de la mise en œuvre effective classe.
  • PowerMock utilise des chargeurs sur mesure (généralement un par classe d'essai)) afin de générer des versions modifiées de la moqué de classes. Une telle utilisation intensive de classe personnalisée chargeurs peuvent conduire à conflits avec des bibliothèques tierces, d'où la nécessité d' parfois l'utilisation de la @PowerMockIgnore ("paquet.to.sois.ignoré") annotation sur les classes d'essai.
  • Le mécanisme utilisé par JMockit (instrumentation dynamique par le biais d'un "Java agent") est plus simple et plus sûr, bien que cela nécessite une paramètre "- javaagent " de la JVM lorsque développement sur JDK 1.5; sur JDK 1.6+ (qui peut toujours être utilisé pour les développement, même si le déploiement sur un ancienne version) il n'y a pas de tels exigence, depuis JMockit peut de manière transparente charge la Java agent sur la demande en utilisant l'attachement de l'API.

un autre outil de moquerie récent est Mockito. Bien qu'il ne tente pas pour surmonter les limites des anciens outils (jMock, EasyMock), il ne introduire un nouveau style de comportement des tests avec des simulacres. JMockit aussi prend en charge ce style alternatif, par le biais de la vérification de l'API.

JMockit vs Mockito

  • Mockito s'appuie sur appels explicites à son API afin de séparer le code entre l'enregistrement (lorsque(...)) et vérifier (vérifier(...)) phase. Ce signifie que toute invocation d'une maquette l'objet dans le code d'essai exigera également un appel à la dérision de l'API. En outre, ce sera souvent conduire à répétitif lorsqu'(...) et vérifier(mock)... appeler.
  • avec JMockit, aucun appel similaire n'existe. Bien sûr, nous avons la nouvelle NonStrictExpectations () et nouveau Vérifications() constructeur appelle, mais ils ne se produisent qu'une fois par essai (généralement), et sont complètement séparé des invocations à des méthodes moquées et des constructeurs.
  • L'API Mockito contient plusieurs incohérences dans la syntaxe utilisée pour invocations aux méthodes moquées. Dans le phase record, nous avons des appels comme quand(maquette.mockedMethod (args))... alors dans la phase de vérification ce même appel sera écrit comme vérifier(mock).mockedMethod (args). Remarquez que dans le premier cas, l' invocation à moqueméthod est faite directement sur la maquette de l'objet, tandis que dans le deuxième cas est fait sur le objet retourné par verify(mock).
  • JMockit n'a pas de telles incohérences parce que les invocations à méthodes fantaisie sont toujours faites directement sur les instances moquées m'. (Avec une seule exception: pour faire correspondre invocations sur le même moqué exemple, un onInstance(mock) l'appel est utilisé, résultant en un code comme onInstance (mock).mockedMethod(args); la plupart des tests n'aurez pas besoin d'utiliser cette, bien.)
  • tout comme d'autres outils de moquerie qui reposent sur la méthode enchaînement / emballage, Mockito court aussi incohérents syntaxe lors de la buter méthodes void. Par exemple, vous écrivez quand(mockedList.(1)).thenThrow(nouveau RuntimeException ()); pour un non-nul méthode, et doThrow(nouveau RuntimeException ()).quand (mockedList).clair(); pour qu'une annulation. Avec JMockit, c'est toujours la même syntaxe: mockedList.clear (); result = new RuntimeException ();.
  • encore une autre incohérence se produit dans l'utilisation D'espions Mockito: "mocks" qui permettent aux méthodes réelles d'être exécuté sur l'instance espionnée. Pour exemple, si l'espion se réfère à un vide Liste, alors au lieu d'écrire quand(spy.get (0)).thenReturn ("foo") vous aurez besoin d'écrire doReturn ("foo").lorsque(espion).get (0). Avec JMockit, la fonction de moquerie dynamique offre des fonctionnalités similaires à espions, mais sans ce problème depuis méthodes réelles ne se faire exécuter que pendant la phase de relecture.
  • Dans EasyMock et jMock, la première se moquant des Api pour Java, l'accent a été mis entièrement sur l'enregistrement de prévu invocations de méthodes moquées, pour les objets fantaisie que (par défaut) ne pas permettre des invocations inattendues. Ceux Api fournissent également l'enregistrement de invocations autorisées pour objets simulés qui permettent des invocations inattendues, mais il a été traité comme une deuxième classe caractéristique. En outre, avec ces outils il n'y a aucun moyen explicitement vérifier les invocations aux moqueries après le code testé est exercé. Tous ces les vérifications sont effectuées implicitement et automatiquement.
  • Dans Mockito (et aussi dans Unitils Mock), le point de vue opposé est occupé. Toutes les invocations pour simuler des objets cela peut se produire pendant le test, soient enregistrés ou non, sont autorisés, jamais attendu. La vérification est effectuée explicitement après le code sous le test est exercé, jamais automatiquement.
  • les Deux approches sont trop extrêmes, et par conséquent moins qu'optimales. Attentes Et Vérifications De JMockit est la seule API qui autorise développeur pour choisir meilleure combinaison de strictes (prévu par défaut) et non-strict (autorisé par par défaut) se moquer des invocations pour chaque test.
  • pour être plus clair, L'API Mockito présente le défaut suivant. Si vous besoin de vérifier qu'une invocation à un la méthode non-void mocked s'est produite pendant le test, mais le test nécessite une valeur de retour de cette méthode qui est différente de la valeur par défaut pour le type de retour, puis le test Mockito aura le code double: a quand(maquette.someMethod ()).thenReturn (xyz) appel à la phase d'enregistrement, et un vérifier(mock).someMethod () dans le vérifier phase. Avec JMockit, une stricte les attentes peuvent toujours être enregistrées, qui n'aura pas à être explicite vérifié. Alternativement, une invocation compter contrainte (temps = 1) peut être spécifié pour un enregistrement non stricte l'attente (avec Mockito tel les contraintes ne peuvent être spécifiées dans un vérifier(maquette, contrainte) appel).
  • Mockito a une mauvaise syntaxe pour les vérifications dans l'ordre, et pour la pleine vérifications (qui est, en vérifiant que toutes les invocations pour simuler des objets sont explicitement vérifié). Dans la première cas, un objet supplémentaire doit être créé, et les appels à vérifier effectués sur c': Afinde afinde = ordre (mock1), mock2,...). Dans le second cas, les appels comme verifyNoMoreInteractions (mock) ou verifyZeroInteractions(mock1, mock2) besoin d'être fait.
  • avec JMockit, il vous suffit d'écrire new VerificationsInOrder () ou new FullVerifications () au lieu de new Vérifications () (ou nouvelles FullVerificationsInOrder () pour combiner les deux conditions). Pas besoin de préciser quels objets simulés sont impliqués. Aucun appels supplémentaires de l'API moqueuse. Et comme un bonus, en appelant unverifiedInvocations() à l'intérieur d'un bloc de vérification commandé, vous pouvez effectuer des vérifications C'est tout simplement impossible à Mockito.

enfin, la boîte à outils de test JMockit a une plus large portée et plus ambitieux objectifs que d'autres boîtes à outils moqueuses, en afin d'offrir une réponse complète et test sophistiqué du développeur solution. Une bonne API pour se moquer, même sans artificiels limites, n'est pas assez productif, la création de test. Un IDE-agnostique, facile à utiliser, et un outil de couverture de Code bien intégré il est également essentiel, et c'est ce que La couverture de JMockit vise à fournir. Un autre morceau de l'essai de développeur ensemble d'outils qui deviendront plus utiles comme la suite de test augmente en taille est le aptitude à reprendre progressivement les essais après un changement localisé de la production code; c'est également inclus dans le Outil de couverture.

(certes, la source peut être biaisée, mais bien...)

je dirais JMockit . C'est le plus facile à utiliser, flexible, et fonctionne pour à peu près tous les cas, même difficiles et les scénarios quand vous ne pouvez pas contrôler la classe à tester (ou vous ne pouvez pas le briser pour des raisons de compatibilité, etc.).

mes expériences avec JMockit ont été très positives.

131
répondu Hendy Irawan 2016-03-11 16:00:42

j'ai travaillé à la fois avec Mockito et JMockit, et mon expérience avec eux est:

  • Mockito:

    • moquerie implicite (- >meilleure usabilité, mais qui risque de ne pas détecter les appels de méthode non autorisés aux moqueurs)
    • vérification explicite
  • EasyMock:

    • moquerie explicite
    • vérification implicite
  • JMockit:

    • supporte les deux
  • en outre, d'autres avantages de JMockit:

    • si vous vous moquez des méthodes statiques / constructeurs etc (comme étendre une très ancienne base de code sans UT), vous aurez deux choix: 1) Mockito / EasyMock avec Powermock extension ou 2) Jmockit
    • rapport de couverture intégré

personnellement, je préfère JMockit, qui je pense est plus riche et flexible, mais nécessite une courbe d'apprentissage un peu plus raide. Il y a généralement plusieurs façons d'obtenir le même effet moqueur, et nécessite plus de soin lors de la conception des moqueries.

23
répondu Tumer 2017-05-03 07:04:58

j'utilise jMockit seulement en raison de son reflet dans les bibliothèques Deencapsultation.classe. J'aime vraiment le style de Mockito, mais je refuse de changer mon code et de brouiller mon API juste pour qu'un framework de test limité puisse y arriver. Et je suis un fan de tester tout mon code, donc un framework qui ne peut pas facilement tester des méthodes privées n'est pas ce que je veux utiliser.

j'ai été influencé par cet article

après un (certes grand) courbe d'apprentissage, jMockit est maintenant mon principal cadre d'essai de l'unité pour les moqueurs.

15
répondu Joseph Erickson 2017-06-26 16:45:01

pour tester facilement notre base de codes legacy (avec beaucoup d'appels de méthodes statiques, etc.), JMockit a été inestimable. [Fiche sans vergogne pour un article sur mon blog]

4
répondu Jeff Olson 2010-11-30 19:16:59

personnellement, je préfère EasyMock .

La possibilité de détourner entre des contrôles de moquerie nice, normal et strict est l'un de mes favoris.

0
répondu Bivas 2010-11-05 12:34:58