المقارنة بين Mockito vs Jmockit - لماذا تم تصويت Mockito أفضل من Jmockit؟ [مغلق

StackOverflow https://stackoverflow.com/questions/4105592

سؤال

أنا أتحقق من إطار السخرية الذي يجب استخدامه في مشروعي وضيقته JMockit و mockito.

انا الاحظ ذلك mockito تم التصويت "أفضل إطار عمل وهمية لجافا"على stackoverflow.
في مقارنة الميزات على JMockit'س "مصفوفة أدوات الاستهزاء" يبدو أنه JMockit لديه ميزات مختلفة متعددة.

هل لدى أي شخص أي معلومات محددة (وليس آراء) حول ماذا mockito يمكن أن تفعل ما لا يمكن تحقيقه JMockit والعكس صحيح؟

هل كانت مفيدة؟

المحلول

تحديث SEP 2019: الوحيد إطار السخرية المدعوم (بشكل افتراضي) عن طريق الحذاء الربيعي هو mockito. إذا كنت تستخدم الربيع ، فإن الإجابة واضحة تمامًا.


أود أن أقول إن المنافسة بين JMockit و Powermock, ، ومن بعد mockito.

سأترك "عادي" Jmock و Easymock لأنهم يستخدمون فقط Proxy & Cglib ولا يستخدمون أجهزة Java 5 مثل الأطر الأحدث.

لم يكن لدى Jmock أيضًا إصدار مستقر لأكثر من 4 سنوات. يتطلب JMock 2.6.0 عامين من RC1 إلى RC2 ، ثم قبل عامين آخرين من إطلاق سراحه بالفعل.

بخصوص الوكيل و CGLIB مقابل الأجهزة:

(Easymock و Jmock) تعتمد على java.lang.reflect.proxy ، والتي تتطلب تنفيذ واجهة. بالإضافة إلى ذلك ، فهي تدعم إنشاء كائنات وهمية للفئات من خلال توليد الفئة الفرعية CGLIB. ولهذا السبب ، لا يمكن أن تكون الفئات المذكورة نهائية ويمكن السخرية من أساليب المثيلات القابلة للتجاوز. الأهم من ذلك ، عند استخدام هذه الأدوات ، يجب أن يتم التحكم في التبعيات من الكود قيد الاختبار (أي ، كائنات الفئات الأخرى التي تعتمد عليها فئة معينة قيد الاختبار) ، بحيث يمكن تمرير مثيلات وهمية إلى العملاء من تلك التبعيات. لذلك ، لا يمكن ببساطة إنشاء التبعيات مع المشغل الجديد في فئة العميل التي نريد كتابة اختبارات الوحدة من أجلها.

في نهاية المطاف ، تفرض القيود التقنية لأدوات السخرية التقليدية قيود التصميم التالية على رمز الإنتاج:

  1. يجب أن يكون كل فئة قد تحتاج إلى السخرية في الاختبار إما تنفيذ واجهة منفصلة أو لا تكون نهائية.
  2. يجب الحصول على تبعيات كل فئة المراد اختبارها إما من خلال طرق إنشاء المثيل القابلة للتكوين (المصانع أو محدد موقع الخدمة) ، أو التعرض لحقن التبعية. خلاف ذلك ، لن تكون اختبارات الوحدة قادرة على تمرير تطبيقات التبعيات الوهمية إلى الوحدة قيد الاختبار.
  3. نظرًا لأنه يمكن استيعاب طرق المثيل فقط ، لا يمكن للفصول التي سيتم اختبارها وحدة الاختبار استدعاء أي طرق ثابتة على تبعياتها ، أو إنشاء مثيل لها باستخدام أي من المُنشئين.

يتم نسخ ما ورد أعلاه من http://jmockit.org/about.html . علاوة على ذلك ، فإنه يقارن بينه (JMockit) و PowerMock و Mockito بعدة طرق:

هناك الآن أدوات سخرية أخرى لـ Java والتي تتغلب أيضًا على القيود المفروضة على الأدوات التقليدية ، بينها PowerMock و JeasyTest و MockInject. الشخص الأقرب إلى مجموعة الميزات من JMockit هو PowerMock ، لذلك سأقوم بتقييمها لفترة وجيزة هنا (إلى جانب ذلك ، والآخران أكثر محدودة ولا يبدو أنهما تم تطويرهما بنشاط بعد الآن).

JMockit مقابل PowerMock

  • بادئ ذي بدء ، لا توفر PowerMock واجهة برمجة تطبيقات كاملة للسخرية ، ولكنها بدلاً من ذلك تعمل كملحق لأداة أخرى ، والتي يمكن أن تكون حاليًا easymock أو mockito. من الواضح أن هذه ميزة للمستخدمين الحاليين لتلك الأدوات.
  • Jmockit ، من ناحية أخرى ، توفر واجهات برمجة التطبيقات الجديدة تمامًا ، على الرغم من أن واجهة برمجة التطبيقات الرئيسية (التوقعات) تشبه كل من Easymock و Jmock. على الرغم من أن هذا يخلق منحنى تعليمي أطول ، إلا أنه يسمح أيضًا لـ JMockit بتوفير API أبسط وأكثر اتساقًا وأسهل في استخدام API.
  • بالمقارنة مع واجهة برمجة تطبيقات توقعات JMockit ، فإن PowerMock API أكثر "مستوى منخفض" ، مما يجبر المستخدمين على معرفة وتحديد الفئات التي يجب إعدادها للاختبار (مع @preparefortest ({classa.class ، ...}) ) وتتطلب مكالمات API محددة للتعامل مع أنواع مختلفة من بنيات اللغة التي قد تكون موجودة في رمز الإنتاج: الطرق الثابتة (mockstatic (classa.class) ، المُنشئون (القمع (مُنشئ (classxyz.class)) ، دعوات مُنشأة ( TECENTNEW (aclass.class)) ، وهمية جزئية (createPartialMock (classx.class ، "methodTomock")) ، إلخ.
  • مع توقعات jmockit ، يتم استياء جميع أنواع الأساليب والمقدمات بطريقة إعلانية بحتة ، مع السخرية الجزئية المحددة من خلال التعبيرات العادية في التعليق التوضيحي mocked أو ببساطة "غير مرغوبون" الأعضاء دون أي توقعات مسجلة ؛ وهذا يعني أن المطور يعلن ببساطة بعض "الحقول السهلة" المشتركة لفئة الاختبار ، أو بعض "حقول وهمية محلية" و/أو "معلمات وهمية" لطرق الاختبار الفردية (وفي هذه الحالة الأخيرة ، لن يكون التعليقات التوضيحية المكسورة غالبًا تكون مطلوبة).
  • بعض القدرات المتوفرة في JMockit ، مثل دعم السخرية المتساوي والرمز التجاري ، والأساليب المتجاوز ، وغيرها ، لا يتم دعمها حاليًا في PowerMock. أيضًا ، لا يوجد أي معادلة لقدرة JMockit على التقاط الحالات والتطبيقات الوهمية لأنواع الأساس المحددة مع تنفيذ الاختبار ، دون أن يكون رمز الاختبار نفسه لديه أي معرفة بفئات التنفيذ الفعلية.
  • يستخدم PowerMock لوادر فئة مخصصة (عادةً واحدة لكل فئة اختبار) من أجل إنشاء إصدارات معدلة من الفئات المستهلكة. يمكن أن يؤدي هذا الاستخدام الكثيف لمحملات الفصول الدراسية المخصصة إلى تعارض مع مكتبات الطرف الثالث ، وبالتالي الحاجة إلى استخدام التعليق التوضيحي PowerMockignore ("package.be.be.ignored") في فصول الاختبار.
  • الآلية التي تستخدمها JMockit (أجهزة وقت التشغيل من خلال "عميل Java") هي أبسط وأكثر أمانًا ، على الرغم من أنها تتطلب تمرير معلمة "-javaagent" إلى JVM عند التطوير على JDK 1.5 ؛ على JDK 1.6+ (والذي يمكن استخدامه دائمًا للتطوير ، حتى إذا تم نشره على إصدار أقدم) ، لا يوجد مثل هذا الشرط ، حيث يمكن لـ JMockit تحميل وكيل Java بشفافية عند الطلب باستخدام API.

أداة الاستهزاء الأخيرة الأخيرة هي Mockito. على الرغم من أنها لا تحاول التغلب على قيود الأدوات القديمة (JMock ، Easymock) ، إلا أنها تقدم نمطًا جديدًا من اختبار السلوك مع النسيج. يدعم JMockit هذا النمط البديل ، من خلال API للتحقق.

JMockit vs Mockito

  • تعتمد Mockito على مكالمات واضحة إلى واجهة برمجة التطبيقات الخاصة بها من أجل فصل التعليمات البرمجية بين السجل (عندما (...)) والتحقق (تحقق (...)). هذا يعني أن أي استدعاء إلى كائن وهمية في رمز الاختبار سيتطلب أيضًا مكالمة إلى واجهة برمجة تطبيقات السخرية. بالإضافة إلى ذلك ، سيؤدي هذا في كثير من الأحيان إلى متكررة عندما (...) والتحقق (وهمية) ... المكالمات.
  • مع JMockit ، لا توجد مكالمات مماثلة. من المؤكد أن لدينا مكالمات New NorstricTexpectations () و New Deviciations () ، ولكنها تحدث مرة واحدة فقط لكل اختبار (عادةً) ، وهي منفصلة تمامًا عن الدعوات إلى الأساليب والمقدمات.
  • تحتوي واجهة برمجة تطبيقات Mockito على العديد من التناقضات في بناء الجملة المستخدمة للدعوات إلى الأساليب السخرية. في مرحلة السجل ، لدينا مكالمات مثل عندما (mock.mockedMethod (args)) ... بينما في مرحلة التحقق من نفس الدعوة ، سيتم كتابة نفس الدعوة (Mock) .mockedMethod (args). لاحظ أنه في الحالة الأولى ، يتم إجراء الاحتجاج إلى MockedMethod مباشرة على الكائن الوهمي ، بينما في الحالة الثانية يتم إجراؤها على الكائن الذي تم إرجاعه عن طريق التحقق (Dock).
  • JMockit ليس لديه مثل هذا التناقضات لأن الدعوات إلى الأساليب السخرية تتم دائمًا مباشرة على الحالات التي تم تسهيلها نفسها. (مع استثناء واحد فقط: لمطابقة الدعوات على نفس المثال الذي تم تسهيله ، يتم استخدام مكالمة Oninstance (Mock) ، مما يؤدي إلى رمز مثل Oninstance (Mock) .mockedMethod (args) ؛ لن تحتاج معظم الاختبارات إلى استخدام هذا ، رغم ذلك. )
  • تمامًا مثل أدوات السخرية الأخرى التي تعتمد على السلاسل/التغليف ، فإن Mockito تعمل أيضًا إلى بناء جملة غير متناسق عند تعبير طرق الفراغ. على سبيل المثال ، تكتب عندما (mockedlist.get (1)). للحصول على طريقة غير void ، و dothrow (new RunTimeException ()). لواحد باطل. مع JMockit ، إنه دائمًا نفس بناء الجملة: mockedlist.clear () ؛ النتيجة = new RunTimeException () ؛.
  • يحدث تناقض آخر في استخدام جواسيس Mockito: "Mocks" التي تسمح بتنفيذ الأساليب الحقيقية على مثيل المتجسد. على سبيل المثال ، إذا كانت SPY تشير إلى قائمة فارغة ، فبدلاً من الكتابة عند (spy.get (0)). ثم ، ستحتاج إلى كتابة Doreturn ("foo"). 0). مع JMockit ، توفر ميزة السخرية الديناميكية وظائف مماثلة للجواسيس ، ولكن بدون هذه المشكلة حيث يتم تنفيذ الأساليب الحقيقية فقط خلال مرحلة الإعادة.
  • في Easymock و Jmock ، أول واجهات برمجة التطبيقات الساخرة لـ Java ، كان التركيز بالكامل على تسجيل الدعوات المتوقعة للطرق المهمة ، للكائنات الوهمية التي (افتراضيًا) لا تسمح بدعوات غير متوقعة. توفر واجهات برمجة التطبيقات هذه أيضًا تسجيل الدعوات المسموح بها للكائنات الوهمية التي تسمح بدعوات غير متوقعة ، ولكن تم التعامل مع هذا كميزة من الدرجة الثانية. بالإضافة إلى ذلك ، مع هذه الأدوات ، لا توجد طريقة للتحقق بشكل صريح من الدعوات للسخرية بعد ممارسة الكود قيد الاختبار. يتم تنفيذ جميع هذه التحقيقات ضمنيًا وتلقائيًا.
  • في Mockito (وأيضًا في Mountils Mock) ، يتم أخذ وجهة النظر المعاكسة. جميع الدعوات إلى الكائنات السخرية التي قد تحدث أثناء الاختبار ، سواء تم تسجيلها أم لا ، لا تتوقع أبدًا. يتم إجراء التحقق بشكل صريح بعد ممارسة الكود قيد الاختبار ، ولم يسبق له مثيل.
  • كلا النهجين متطرف للغاية ، وبالتالي أقل من الأمثل. التوقعات والتحققات JMockit هي واجهة برمجة التطبيقات الوحيدة التي تسمح للمطور باختيار أفضل مزيج من الدعوات الصارمة (المتوقعة بشكل افتراضي) وغير المسموح به بشكل افتراضي) لكل اختبار.
  • لكي تكون أكثر وضوحًا ، فإن واجهة برمجة تطبيقات Mockito لديها القصور التالي. إذا كنت بحاجة إلى التحقق من أن الاحتجاج إلى طريقة غير مسبقة غير void حدثت أثناء الاختبار ، لكن الاختبار يتطلب قيمة إرجاع من تلك الطريقة التي تختلف عن الافتراضي لنوع الإرجاع ، فإن اختبار Mockito سيكون له رمز مكرر: A عندما (mock.somemethod ()). مع JMockit ، يمكن دائمًا تسجيل التوقع الصارم ، والذي لن يتم التحقق منه بشكل صريح. بدلاً من ذلك ، يمكن تحديد قيود عدد الاحتجاج (الأوقات = 1) لأي توقعات مسجلة غير مسجلة (مع Mockito مثل هذه القيود لا يمكن تحديدها إلا في مكالمة التحقق (Mock ، القيد)).
  • يحتوي Mockito على بناء جملة ضعيف للتحققات ، وللتحقق الكامل (أي ، التحقق من أن جميع الدعوات إلى الكائنات الوهمية يتم التحقق منها بشكل صريح). في الحالة الأولى ، يجب إنشاء كائن إضافي ، ومكالمات للتحقق منها: inorder inorder = inorder (mock1 ، mock2 ، ...). في الحالة الثانية ، يجب إجراء مكالمات مثل VerifyNomoreInterctions (Mock) أو Verifyzerointerctions (Mock1 ، Mock2).
  • باستخدام JMockit ، يمكنك ببساطة كتابة VivonsiationSinOrder () أو fullverifications () جديدة بدلاً من التحقق الجديد () (أو fullverificationSinorder () الجمع بين كلا المتطلبات). لا حاجة لتحديد الكائنات الوهمية المتورطة. لا مكالمات API سخرية إضافية. وكمكافأة ، من خلال استدعاء عدم التقيد () داخل كتلة التحقق المطلوبة ، يمكنك تنفيذ عمليات التحقق المتعلقة بالطلب والتي من المستحيل ببساطة في Mockito.

أخيرًا ، تحتوي مجموعة أدوات اختبار JMockit على ملف نطاق أوسع و أهداف أكثر طموحا من مجموعات أدوات السخرية الأخرى ، من أجل توفير حل اختبار مطور كامل ومتطور. واجهة برمجة تطبيقات جيدة للسخرية ، حتى بدون قيود اصطناعية ، لا تكفي لإنشاء الاختبارات الإنتاجية. تعد أداة تغطية الكود IDE-AD-Agnostic ، وسهلة الاستخدام ، ومتكاملة جيدًا ، وهذا هو ما يهدف Jmockit Coverage إلى توفيره. هناك جزء آخر من مجموعة أدوات اختبار المطور والتي ستصبح أكثر فائدة مع نمو مجموعة الاختبار في الحجم وهي القدرة على إعادة تشغيل الاختبارات بشكل متزايد بعد تغيير موضعي إلى رمز الإنتاج ؛ يتم تضمين هذا أيضًا في أداة التغطية.

(منحت ، قد يكون المصدر متحيزًا ، لكن حسنًا ...)

أود أن أقول الذهاب مع JMockit. من الأسهل استخدامها ومرونة وتعمل على جميع الحالات إلى حد كبير حتى الحالات والسيناريوهات الصعبة عندما لا يمكنك التحكم في الفصل للاختبار (أو لا يمكنك كسره لأسباب التوافق وما إلى ذلك).

كانت تجربتي مع JMockit إيجابية للغاية.

نصائح أخرى

عملت مع كل من Mockito و Jmockit ، وتجربتي معهم هي:

  • mockito:

    • سخرية ضمنية (-> قابلية استخدام أفضل ، ولكن لديها خطر الفشل في اكتشاف مكالمات الطريقة غير الممسوكة على السخرية)
    • التحقق الصريح
  • easymock:

    • أوضح السخرية
    • التحقق الضمني
  • jmockit:

    • يدعم كليهما
  • إلى جانب ذلك ، فوائد أخرى من jmockit:

    • إذا كنت تسخر من الأساليب/البنائين الثابتة وما إلى ذلك (مثل تمديد قاعدة رمز قديمة جدًا بدون UT) ، سيكون لديك خياران: 1) Mockito/Easymock مع تمديد PowerMock أو 2) JMockit
    • تقرير تغطية مدمج

أنا شخصياً أفضل jmockit ، والتي أعتقد أنها أكثر غنية ومرنة ، ولكنها تتطلب منحنى تعليمي أكثر انحدارًا قليلاً. عادة ما يكون هناك طرق متعددة لتحقيق نفس التأثير الساخط ، ويتطلب المزيد من العناية عند تصميم السخرية.

أنا استخدم jmockit فقط بسبب مكتبات الانعكاس في deencapsultation.class. أنا في الواقع أحب أسلوب Mockito ، لكني أرفض تغيير الكود الخاص بي وتوضع واجهة برمجة التطبيقات الخاصة بي حتى يتمكن إطار اختبار محدود من الوصول إليه. وأنا معجب باختبار جميع التعليمات البرمجية الخاصة بي ، لذا فإن الإطار الذي لا يمكن اختبار الأساليب الخاصة بسهولة ليس ما أريد استخدامه.

لقد تأثرت هذه المقالة

بعد منحنى التعلم (كبير معترف به) ، أصبح JMockit الآن إطار اختبار الوحدة الرئيسي الخاص بي للنهايات.

للاختبار السهل لقاعدة الكود القديمة لدينا (مع الكثير من مكالمات الطريقة الثابتة ، وما إلى ذلك) ، كان JMockit لا يقدر بثمن. [قابس وقح ل مقالة - سلعة على مدونتي

أنا شخصيا أفضل easymock.
القدرة على التحول بين عناصر التحكم السخرية اللطيفة والطبيعية والصارمة هي واحدة على ميزة المفضلة لدي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top