Mockito ile JMockit arasındaki karşılaştırma - Mockito neden JMockit'ten daha iyi oy kullanıyor? [kapalı]


124

Projem için hangi alay çerçevesini kullanacağımı araştırıyorum ve onu JMockit ve Mockito'ya indirgedim .

Mockito'nun Stackoverflow'da " Java için en iyi sahte çerçeve " seçildiğini fark ettim .
Üzerinde özelliklerini karşılaştıran JMockit 'ın ' alaycı Aracı Karşılaştırılması Matrix ' şunlar anlaşılmaktadır JMockit birden fazla farklı özelliklere sahiptir.

Mockito'nun neler yapabileceği konusunda JMockit ile elde edilemeyen ve bunun tersi olan herhangi bir özel bilgiye (fikirleri olmayan) var mı?


2
belki mockito için daha iyi kullanılabilirlik, btw JMockit'in Mockito'dan daha olgun olduğunu düşünmüyorum ...
Alois Cochard

42
Oy sayısına bakılırsa, KESİNLİKLE bu sorunun yanıtları topluluk tarafından çok aranmaktadır. Bu, bu sorunun kapatılmasına neden olan bu sitenin ortogonalleştirme stratejisinin ciddi bir yeniden düşünmeyi gerektirdiği anlamına gelir - çünkü bu site, yanlış hizalanmış ortogonelliğine düşerek gerekli cevapları sağlayabilmek için sık sık kendi ayağına ayak basmıştır. Bir ağacın grafik analizinde, bir ağacın dikliğini görmenin düğümler kadar birçok yolu olduğunu fark etmemek. Belki de bu sitenin sorudan ziyade ortogonalliği yanlış hizalanmıştır.
Blessed Geek

9
Kapatmamak için +1. Bu cevapların tonlarca değeri var. Bir teknoloji seçmek kolay değildir ve bu sorular çok zaman kazandırabilir. Aslında doğru bir cevap olmayabilir, ancak StackOverflow, soru sorulmadan cevaplanmalıdır.
mhstnsc

6
Bunu "yapıcı değil" diye kapatmanın saçma olduğunu söyleyenlere desteğimi ekleyeceğim. Burada verilen yanıtlar "gerçekler, referanslar ve / veya uzmanlık" ile desteklenmiştir. Teknoloji alanında bazı "münazaralar, oylamalar veya uzun tartışmalar" istemeyen bir soru genellikle zar zor sorulmaya değerdir. Dahası, gerçeklerin ve uzmanlığın sağlanması farklı deneyimlere dayanır ve bu farklılıklar, tartışmalara ve uzun tartışmalara yol açacaktır.
Jeff Nyman

@Alois - JMockit'in Mockito'dan daha az olgun göründüğü somut örnekler verebilir misiniz?
NitinS

Yanıtlar:


139

Güncelleme Eylül 2019: Sadece İlkbahar Boot tarafından (varsayılan olarak) desteklenen alay çerçeve olduğunu mockito . Spring'i kullanırsanız, cevap oldukça açıktır.


Rekabetin JMockit ile PowerMock arasında , ardından Mockito arasında olduğunu söyleyebilirim .

"Düz" jMock ve EasyMock'u bırakırım çünkü sadece proxy ve CGLIB kullanıyorlar ve daha yeni çerçeveler gibi Java 5 enstrümantasyonunu kullanmıyorlar.

jMock ayrıca 4 yıldan uzun süredir kararlı bir sürüme sahip değildi. jMock 2.6.0, RC1'den RC2'ye geçiş için 2 yıl ve ardından fiilen piyasaya sürülmeden önce 2 yıl daha gerektirdi.

Proxy & CGLIB ile enstrümantasyonla ilgili olarak:

(EasyMock ve jMock), uygulanacak bir arabirim gerektiren java.lang.reflect.Proxy'yi temel alır. Ek olarak, CGLIB alt sınıf oluşturma yoluyla sınıflar için sahte nesnelerin oluşturulmasını desteklerler. Bu nedenle, söz konusu sınıflar nihai olamaz ve yalnızca geçersiz kılınabilen örnek yöntemleri alay edilebilir. Ancak en önemlisi, bu araçları kullanırken test edilen kodun bağımlılıkları (yani, test edilen belirli bir sınıfın bağlı olduğu diğer sınıfların nesneleri) testler tarafından kontrol edilmelidir, böylece sahte örnekler istemcilere aktarılabilir. bu bağımlılıkların. Bu nedenle, birim testleri yazmak istediğimiz bir istemci sınıfında bağımlılıklar yeni operatörle basitçe somutlaştırılamaz.

Nihayetinde, geleneksel alay araçlarının teknik sınırlamaları, üretim koduna aşağıdaki tasarım kısıtlamalarını getirir:

  1. Bir testte alay edilmesi gerekebilecek her sınıf ya ayrı bir arayüz uygulamalı ya da nihai olmamalıdır.
  2. Test edilecek her bir sınıfın bağımlılıkları, yapılandırılabilir örnek oluşturma yöntemleri (fabrikalar veya bir Hizmet Bulucu) aracılığıyla elde edilmeli veya bağımlılık ekleme için açığa çıkarılmalıdır. Aksi takdirde, birim testleri, bağımlılıkların sahte uygulamalarını test edilen birime geçiremeyecektir.
  3. Yalnızca örnek yöntemler alay edilebildiğinden, birim test edilecek sınıflar bağımlılıkları için herhangi bir statik yöntem çağıramaz veya bunları yapıcılardan herhangi birini kullanarak başlatamaz.

Yukarıdakiler http://jmockit.org/about.html adresinden kopyalanmıştır . Ayrıca kendisi (JMockit), PowerMock ve Mockito arasında çeşitli şekillerde karşılaştırma yapar:

PowerMock, jEasyTest ve MockInject aralarında geleneksel olanların sınırlamalarının da üstesinden gelen Java için artık başka alay araçları var. JMockit'in özellik setine en yakın olanı PowerMock'dur, bu yüzden burada kısaca değerlendireceğim (ayrıca diğer ikisi daha sınırlı ve artık aktif olarak geliştirilmiyor gibi görünüyor).

JMockit ve PowerMock

  • Her şeyden önce, PowerMock alay için eksiksiz bir API sağlamaz, bunun yerine şu anda EasyMock veya Mockito olabilen başka bir aracın uzantısı olarak çalışır. Bu, bu araçların mevcut kullanıcıları için açıkça bir avantajdır.
  • Öte yandan JMockit, ana API'si (Beklentiler) hem EasyMock hem de jMock'a benzese de, tamamen yeni API'ler sağlar. Bu, daha uzun bir öğrenme eğrisi oluştururken, JMockit'in daha basit, daha tutarlı ve kullanımı daha kolay bir API sağlamasına da olanak tanır.
  • JMockit Expectations API ile karşılaştırıldığında, PowerMock API daha "düşük seviyelidir" ve kullanıcıları test için hangi sınıfların hazırlanması gerektiğini bulmaya ve belirlemeye zorlar (@PrepareForTest ({ClassA.class, ...}) ek açıklaması ile ) ve üretim kodunda bulunabilecek çeşitli dil yapı türleriyle ilgilenmek için belirli API çağrıları gerektirmesi: statik yöntemler (mockStatic (ClassA.class)), yapıcılar (bastır (yapıcı (ClassXyz.class))), yapıcı çağrıları ( waitNew (AClass.class)), kısmi örnekler (createPartialMock (ClassX.class, "methodToMock")), vb.
  • JMockit Beklentileriyle, her türlü yöntem ve kurucu, @Mocked ek açıklamasında normal ifadeler aracılığıyla belirtilen kısmi alaylarla veya kayıtlı beklentileri olmayan üyelerin sadece "alay edilmesinden" tamamen açıklayıcı bir şekilde alay edilir; yani geliştirici, test sınıfı için bazı paylaşılan "sahte alanlar" veya bireysel test yöntemleri için bazı "yerel sahte alanlar" ve / veya "sahte parametreler" bildirir (ve bu son durumda @Mocked ek açıklaması genellikle ihtiyaç duyulabilir).
  • JMockit'te bulunan, eşittir ve hashCode alay desteği, geçersiz kılınan yöntemler ve diğerleri gibi bazı yetenekler şu anda PowerMock'ta desteklenmemektedir. Ayrıca, test kodunun kendisi gerçek uygulama sınıfları hakkında herhangi bir bilgiye sahip olmadan, JMockit'in test yürütürken belirtilen temel türlerin örneklerini ve sahte uygulamalarını yakalama becerisinin bir eşdeğeri yoktur.
  • PowerMock, alay edilen sınıfların değiştirilmiş sürümlerini oluşturmak için özel sınıf yükleyicileri (genellikle her test sınıfı için bir tane) kullanır. Özel sınıf yükleyicilerin bu kadar yoğun kullanımı, üçüncü taraf kitaplıklarıyla çakışmalara yol açabilir, bu nedenle test sınıflarında bazen @PowerMockIgnore ("package.to.be.ignored") ek açıklamasını kullanma ihtiyacı doğabilir.
  • JMockit tarafından kullanılan mekanizma (bir "Java aracısı" aracılığıyla çalıştırma zamanı enstrümantasyonu) daha basit ve daha güvenlidir, ancak JDK 1.5 üzerinde geliştirilirken JVM'ye bir "-javaagent" parametresinin aktarılmasını gerektirir; JDK 1.6+ üzerinde (eski bir sürümde konuşlandırılsa bile geliştirme için her zaman kullanılabilir) böyle bir gereksinim yoktur çünkü JMockit, Attach API'yi kullanarak isteğe bağlı olarak Java aracısını şeffaf bir şekilde yükleyebilir.

Bir başka yeni alay aracı Mockito'dur. Eski araçların (jMock, EasyMock) sınırlamalarının üstesinden gelmeye çalışmasa da, alaylarla yeni bir davranış testi stili sunar. JMockit, Doğrulama API'si aracılığıyla bu alternatif stili de destekler.

JMockit ve Mockito

  • Mockito, kodu kayıt (ne zaman (...)) ve doğrulama (doğrulama (...)) aşamaları arasında ayırmak için API'sine yapılan açık çağrılara güvenir. Bu, test kodundaki bir sahte nesneye yapılan herhangi bir çağrının, alay API'sine bir çağrı gerektireceği anlamına gelir. Ek olarak, bu genellikle (...) ve doğrulama (sahte) ... çağrılarının tekrarlanmasına yol açar.
  • JMockit ile benzer çağrılar yoktur. Elbette, yeni NonStrictExpectations () ve yeni Verifications () yapıcı çağrılarına sahibiz, ancak bunlar test başına yalnızca bir kez (tipik olarak) gerçekleşir ve çağrılardan alay edilen yöntemlere ve yapıcılara tamamen ayrıdır.
  • Mockito API, alay edilen yöntemlere yapılan çağrılar için kullanılan söz diziminde birkaç tutarsızlık içerir. Kayıt aşamasında, when (mock.mockedMethod (args)) gibi çağrılarımız var ... doğrulama aşamasında bu çağrı doğrulama (mock) .mockedMethod (args) olarak yazılacak. İlk durumda mockedMethod çağrısının doğrudan sahte nesne üzerinde yapıldığına, ikinci durumda ise doğrulama (mock) ile döndürülen nesne üzerinde yapıldığına dikkat edin.
  • JMockit'in bu tür tutarsızlıkları yoktur, çünkü alay edilen yöntemlere yapılan çağrılar her zaman doğrudan alay edilen örnekler üzerinde yapılır. (Yalnızca bir istisna dışında: aynı alay edilen örnekteki çağrıları eşleştirmek için onInstance (sahte) çağrısı kullanılır ve sonuç olarak onInstance (mock) .mockedMethod (args) gibi bir kod elde edilir; yine de çoğu testin bunu kullanması gerekmez. )
  • Metod zincirleme / sarmalamaya dayanan diğer alay araçları gibi, Mockito da void yöntemlerini saplarken tutarsız sözdizimiyle karşılaşır. Örneğin, (mockedList.get (1)). ThenThrow (new RuntimeException ()); geçersiz olmayan bir yöntem için ve doThrow (new RuntimeException ()). when (mockedList) .clear (); geçersiz olan için. JMockit ile her zaman aynı sözdizimi vardır: mockedList.clear (); sonuç = new RuntimeException () ;.
  • Mockito casuslarının kullanımında bir başka tutarsızlık daha ortaya çıkar: gerçek yöntemlerin casusluk örneğinde yürütülmesine izin veren "taklitler". Örneğin, casus boş bir Listeye atıfta bulunuyorsa, ne zaman (spy.get (0)). ThenReturn ("foo") yazmak yerine doReturn ("foo") yazmanız gerekir. When (spy) .get ( 0). JMockit ile dinamik alay özelliği casuslara benzer işlevsellik sağlar, ancak bu sorun olmadan gerçek yöntemler yalnızca yeniden oynatma aşamasında çalıştırılır.
  • Java için ilk alay API'leri olan EasyMock ve jMock'ta, odak noktası tamamen beklenmedik çağrılara izin vermeyen sahte nesneler için (varsayılan olarak) sahte yöntemlerin beklenen çağrılarının kaydedilmesiydi. Bu API'ler ayrıca, beklenmedik çağrılara izin veren sahte nesneler için izin verilen çağrıların kaydını sağlar, ancak bu ikinci sınıf bir özellik olarak değerlendirildi. Ek olarak, bu araçlarla, test edilen kod uygulandıktan sonra sahte çağrılara yapılan çağrıları açıkça doğrulamanın bir yolu yoktur. Tüm bu doğrulamalar dolaylı ve otomatik olarak yapılır.
  • Mockito'da (ve ayrıca Unitils Mock'ta) zıt bakış açısı alınır. Kaydedilmiş olsun veya olmasın, test sırasında meydana gelebilecek tüm sahte nesnelere çağrılara izin verilir, asla beklenmez. Doğrulama, test edilen kod uygulandıktan sonra açıkça gerçekleştirilir, asla otomatik olarak yapılmaz.
  • Her iki yaklaşım da çok aşırı ve dolayısıyla optimalden daha az. JMockit Beklentiler ve Doğrulamalar, geliştiricinin her test için katı (varsayılan olarak beklenen) ve katı olmayan (varsayılan olarak izin verilir) sahte çağrıların en iyi kombinasyonunu sorunsuz bir şekilde seçmesine olanak tanıyan tek API'dir.
  • Daha açık olmak gerekirse, Mockito API aşağıdaki eksikliklere sahiptir. Test sırasında geçersiz olmayan bir alay yöntemine çağrı yapıldığını doğrulamanız gerekiyorsa ancak test, bu yöntemden dönüş türü için varsayılandan farklı bir dönüş değeri gerektiriyorsa, Mockito testinde yinelenen kod olacaktır: a kayıt aşamasında (mock.someMethod ()). thenReturn (xyz) çağrısı ve doğrulama aşamasında bir doğrulama (mock) .someMethod (). JMockit ile, açıkça doğrulanması gerekmeyen katı bir beklenti her zaman kaydedilebilir. Alternatif olarak, kaydedilen herhangi bir katı olmayan beklenti için bir çağrı sayısı kısıtlaması (zamanlar = 1) belirtilebilir (Mockito ile bu tür kısıtlamalar yalnızca bir doğrulama (sahte, kısıtlama) çağrısında belirtilebilir).
  • Mockito, sırayla doğrulamalar ve tam doğrulamalar için zayıf sözdizimine sahiptir (yani, tüm sahte nesnelere çağrıların açıkça doğrulandığını kontrol eder). İlk durumda, fazladan bir nesnenin oluşturulması ve üzerinde doğrulama çağrılarının yapılması gerekir: InOrder inOrder = inOrder (mock1, mock2, ...). İkinci durumda, validNoMoreInteractions (mock) veya validZeroInteractions (mock1, mock2) gibi çağrıların yapılması gerekir.
  • JMockit ile, her iki gereksinimi birleştirmek için yeni Verifications () (veya yeni FullVerificationsInOrder () yerine yeni VerificationsInOrder () veya yeni FullVerifications () yazmanız yeterlidir. Hangi sahte nesnelerin dahil olduğunu belirtmeye gerek yok. Fazladan alaycı API çağrısı yok. Ve bonus olarak, sıralı bir doğrulama bloğu içinde unverifiedInvocations () çağırarak, Mockito'da kesinlikle imkansız olan siparişle ilgili doğrulamaları gerçekleştirebilirsiniz.

Son olarak, JMockit Testing Toolkit, eksiksiz ve sofistike bir geliştirici test çözümü sağlamak için diğer alay araç setlerinden daha geniş bir kapsama ve daha iddialı hedeflere sahiptir. Yapay sınırlamalar olmadan bile alay için iyi bir API, testlerin verimli bir şekilde oluşturulması için yeterli değildir. IDE'den bağımsız, kullanımı kolay ve iyi entegre edilmiş bir Kod Kapsamı aracı da gereklidir ve JMockit Kapsamı bunu sağlamayı amaçlamaktadır. Test paketinin boyutu büyüdükçe daha kullanışlı hale gelecek olan geliştirici test araç setinin bir başka parçası da, üretim kodunda yerelleştirilmiş bir değişiklikten sonra testleri aşamalı olarak yeniden çalıştırma yeteneğidir; bu aynı zamanda Kapsam aracına da dahildir.

(verilmiş, kaynak önyargılı olabilir, ancak iyi ...)

JMockit ile git derim . Kullanımı en kolay, esnektir ve test edilecek sınıfı kontrol edemediğinizde (veya uyumluluk nedenleriyle vb. Kıramadığınızda) zor olanlar ve senaryolar için bile hemen hemen tüm durumlarda işe yarar.

JMockit ile deneyimlerim çok olumlu oldu.


1
Hiç jmockit kullanmadım, ancak tartışmaya başka bir argüman eklemek istiyorum: tartışılan tüm çerçevelerin google trendleri karşılaştırmasına bir göz atın. 06.06.2012 itibarıyla JMockit, Mockito ve EasyMock ile karşılaştırıldığında google trendler grafiğinde bile görünmüyor. Bir çerçeve seçerken kullanıcı sayısı da önemlidir.
makine

3
Bu oldukça tuhaf. Mockito ve JMockIt bana google'da sırasıyla 409 've 83' hit veriyor. Şüphesiz JMockIt en azından görünmelidir.
thoredge

5
Cevabınız çok yardımcı oldu. Sadece Mockito'yu kullanmayı planladım, ancak şimdi önce JMockit'i test edeceğim. Denememek kulağa hoş geliyor. @machinery: Evet, trendlere bakmak önemli ama bunu ana kriter olarak seçmek sizi ana akımla sınırlayacak ve sizi inovasyondan koruyacaktır.
deamon

1
Bunun eski bir konu olduğunu biliyorum, ancak bu incelemeyi okuduktan sonra bir şans vereceğimi düşündüm. Yüzeyde JMockit'in çok umut verici olduğunu söylemeliyim. Ancak bugüne kadar, bunun için topluluk desteğini çok eksik buldum. Mock API'yi anlamamla ilgili büyük bir sorun yaşıyorum ve sorunlarımı yayınladıktan sonra 2 gün içinde yanıt alamadım.
Eric B.

1
Cevap 8 yaşında, cevaptaki pek çok şey artık doğru değil. Bir nokta, JMockit'in 1.42'den -javaagentberi bayrak gerektirmesidir çünkü artık Java 9'dan beri kendi kendine bağlanamazsın ve uygun geçici çözümler bulmak geliştiricinin kapsamında değildi. Başka bir nokta da, PowerMock afaik yaparken JMockit'in artık özel yöntemler ve kurucularla dalga geçmesine izin vermemesidir.
Vampire

24

Hem Mockito hem de JMockit ile çalıştım ve onlarla olan deneyimim:

  • mockito:

    • örtük alay (-> daha iyi kullanılabilirlik, ancak taklitlerde izin verilmeyen yöntem çağrılarını tespit edememe tehlikesi vardır)
    • açık doğrulama
  • EasyMock:

    • alay etmek
    • örtük doğrulama
  • JMockit:

    • ikisini de destekler
  • Ayrıca, JMockit'in diğer faydaları:

    • Statik yöntemleri / yapıcıları vb. alay ediyorsanız (UT olmadan çok eski bir eski kod tabanını genişletmek gibi), iki seçeneğiniz vardır: 1) Mockito / Powermock uzantılı EasyMock veya 2) Jmockit
    • yerleşik kapsama raporu

Ben şahsen JMockit'i tercih ediyorum, ki bu daha çok özellikli ve esnek ama biraz daha dik öğrenme eğrisi gerektiriyor. Aynı alay etkisini elde etmenin genellikle birden fazla yolu vardır ve alayları tasarlarken daha fazla özen gerektirir.


orada stackoverflow.com/questions/8003278/... "verifyNoMoreInteractions" Eğer Mockito ile sözde açık alaycı istiyorsanız herhalde
rogerdpack

15

JMockit'i yalnızca Deencapsultation.class içindeki yansıma kitaplıkları nedeniyle kullanıyorum. Aslında Mockito'nun tarzını seviyorum, ancak kodumu değiştirmeyi reddediyorum ve API'mi çamurlu hale getiriyorum, böylece sınırlı bir test çerçevesi ona ulaşabilir. Ve tüm kodumu test etme hayranıyım, bu yüzden özel yöntemleri kolayca test edemeyen bir çerçeve kullanmak istediğim şey değil.

Bu yazı beni etkiledi

(Kuşkusuz büyük) bir öğrenme eğrisinden sonra, jMockit artık taklitler için ana birim test çerçevem.


7
Belki de özel yöntemleri test etmeniz gerektiğini düşünüyorsanız, kodunuzun ne işe yaradığından ziyade nasıl çalıştığı ile çok ilgileniyorsunuzdur (bu gerçek nokta ve hangisi sadece genel yöntemlerini uygulayarak belirlenebilir). Bir de o makaleyi okumak isterdim ama bağlantı koptu.
codebox

4 yıl sonra, jMockit'i hala birincil test çerçeveniz olarak mı kullanıyorsunuz? İlk kez deniyorum ve onunla birkaç sorunla karşılaşıyorum ama jMockit'in nasıl çalıştığını yanlış anlamam mı, yoksa var olmayan bir özellik mi bilmiyorum.
Eric B.

jMockit artık özel yöntemleri test etmeyi desteklemiyor. Deencapsulation sınıfı yavaş yavaş kullanımdan kaldırıldı ve ardından 1.47 sürümünde tamamen kaldırıldı. jmockit.github.io/changes.html
Pytry

4

Eski kod tabanımızın (çok sayıda statik yöntem çağrısı vb. İle) kolay test edilmesi için JMockit paha biçilmezdir. [ Blogumdaki bir makale için utanmaz eklenti ]


0

Ben şahsen EasyMock'u tercih ediyorum .
Hoş, normal ve katı alay kontrolleri arasında geçiş yapma yeteneği, en sevdiğim özelliklerden biridir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.