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:
- Bir testte alay edilmesi gerekebilecek her sınıf ya ayrı bir arayüz uygulamalı ya da nihai olmamalıdır.
- 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.
- 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.