Java'da sahte nesneler oluşturmak için en iyi çerçeve hangisidir? Neden? Her çerçevenin artıları ve eksileri nelerdir?
Java'da sahte nesneler oluşturmak için en iyi çerçeve hangisidir? Neden? Her çerçevenin artıları ve eksileri nelerdir?
Yanıtlar:
Mockito'yu kullanırken başarılı oldum .
JMock ve EasyMock'u öğrenmeyi denediğimde, öğrenme eğrisinin biraz dik olduğunu fark ettim (belki de bu sadece benim).
Mockito'yu basit ve temiz sözdizimi sayesinde çok çabuk kavrayabildiğim için seviyorum. Minimal sözdizimi, yaygın vakaları çok iyi desteklemek için tasarlanmıştır, ancak birkaç kez daha karmaşık bir şey yapmak zorunda kaldım, istediğim şeyi destekledim ve kavramak kolay buldum.
İşte Mockito ana sayfasından (kısaltılmış) bir örnek:
import static org.mockito.Mockito.*;
List mockedList = mock(List.class);
mockedList.clear();
verify(mockedList).clear();
Bundan daha basit olamaz.
Düşünebildiğim tek büyük dezavantajı, statik yöntemlerle alay etmeyecek olmasıdır.
PowerMock'un yaratıcısıyım, bu yüzden bunu tavsiye etmeliyim! :-)
PowerMock , hem EasyMock hem de Mockito'yu statik yöntemler , son ve hatta özel yöntemler ile alay etme yeteneği ile genişletir . EasyMock desteği tamamlandı, ancak Mockito eklentisinin biraz daha çalışması gerekiyor. JMock desteğini de eklemeyi planlıyoruz.
PowerMock, diğer çerçeveleri değiştirmek için tasarlanmamıştır, bunun yerine diğer çerçevelerin alay etmesine izin vermediği zorlu durumlarda kullanılabilir. PowerMock ayrıca statik başlatıcıları ve yapıcıları baskılamak gibi diğer kullanışlı özellikleri de içerir .
JMockit proje sitesi akım alaycı araci karşılaştırmalı pek çok bilgi içeriyor.
Özellikle, EasyMock, jMock, Mockito, Unitils Mock, PowerMock ve elbette JMockit'i kapsayan özellik karşılaştırma matrisine göz atın. Mümkün olduğunca doğru ve güncel tutmaya çalışıyorum.
JMockit ile başarılı oldum .
Oldukça yeni ve bu yüzden biraz ham ve belgelenmemiş. Sınıf bayt kodunu dinamik olarak yeniden tanımlamak için ASM kullanır , böylece statik, özel, yapıcılar ve statik başlatıcılar dahil tüm yöntemleri alay edebilir. Örneğin:
import mockit.Mockit;
...
Mockit.redefineMethods(MyClassWithStaticInit.class,
MyReplacementClass.class);
...
class MyReplacementClass {
public void $init() {...} // replace default constructor
public static void $clinit{...} // replace static initializer
public static void myStatic{...} // replace static method
// etc...
}
Kayıt / oynatma senaryolarına da izin veren bir Beklentiler arayüzü vardır:
import mockit.Expectations;
import org.testng.annotations.Test;
public class ExpecationsTest {
private MyClass obj;
@Test
public void testFoo() {
new Expectations(true) {
MyClass c;
{
obj = c;
invokeReturning(c.getFoo("foo", false), "bas");
}
};
assert "bas".equals(obj.getFoo("foo", false));
Expectations.assertSatisfied();
}
public static class MyClass {
public String getFoo(String str, boolean bool) {
if (bool) {
return "foo";
} else {
return "bar";
}
}
}
}
Dezavantajı, Java 5/6 gerektirmesidir.
Groovy kullanarak testlere de göz atabilirsiniz. Groovy'de 'as' operatörünü kullanarak Java arayüzlerini kolayca taklit edebilirsiniz:
def request = [isUserInRole: { roleName -> roleName == "testRole"}] as HttpServletRequest
Bu temel işlevsellik dışında Groovy, güçlü MockFor
ve StubFor
sınıflar da dahil olmak üzere alaycı cephede çok daha fazlasını sunuyor .
EasyMock ile alay kullanmaya başladım . Anlamak yeterince kolay, ancak tekrar adımı biraz sinir bozucuydu. Mockito bunu kaldırır, ayrıca okunabilirliğin birincil hedeflerinden biri gibi göründüğü için daha temiz bir sözdizimine sahiptir. Bunun ne kadar önemli olduğunu vurgulayamıyorum, çünkü geliştiricilerin çoğu mevcut kodu okumak ve korumak için zaman harcayacaklar, onu yaratmak değil.
Bir başka güzel şey de, EasyMock Sınıf Uzantısını kullanmak için hatırlamanız gereken (ve kontrol ettiğiniz) EasyMock'un aksine arayüzler ve uygulama sınıflarının aynı şekilde ele alınmasıdır.
Geçenlerde JMockit hızlı bir göz attım ve özellikler çamaşır listesi oldukça kapsamlı olsa da, bunun fiyat ortaya çıkan kod okunabilirliği ve daha fazla yazmak zorunda olduğunu düşünüyorum.
Benim için Mockito tatlı noktaya vuruyor, yazması ve okuması kolay ve çoğu kodun gerektireceği durumların çoğuyla uğraşıyor. Kullanılması Mockito ile PowerMock benim seçimim olurdu.
Dikkate almanız gereken bir şey, kendiniz veya küçük sıkı bir ekipte gelişirseniz seçeceğiniz aracın, farklı beceri düzeylerine sahip geliştiricileri olan büyük bir şirket için en iyi seçenek olmayabilir. Okunabilirlik, kullanım kolaylığı ve basitlik ikinci durumda daha fazla dikkate alınmalıdır. Bir çok insan onu kullanmıyorsa veya testleri sürdürmüyorsa nihai alaycı çerçeveyi elde etmenin bir anlamı yok.
EasyMock ve EasyMock Class Extension'ı işte yoğun bir şekilde kullanıyoruz ve bundan oldukça memnunuz. Temel olarak ihtiyacınız olan her şeyi verir. Belgelere bir bakın, EasyMock'un tüm özelliklerini gösteren çok güzel bir örnek var.
JMock'u erken kullandım. Mockito'yu son projemde denedim ve beğendim. Daha özlü, daha temiz. PowerMock, Mockito'da bulunmayan, statik bir kodu alay etme, bir örnek oluşturma alay etme, son sınıfları ve yöntemleri alay etme gibi tüm ihtiyaçları kapsar. Yani işimi yapmak için ihtiyacım olan her şeye sahibim.
JMock'u seviyorum çünkü beklentileri ayarlayabilirsiniz. Bu, bazı sahte kitaplıklarda bir yöntemin çağrılıp çağrılmadığını denetlemekten tamamen farklıdır. JMock'u kullanarak çok karmaşık beklentiler yazabilirsiniz. Jmock hile kılıfına bakın .
Evet, Mockito harika bir çerçeve. Testlerimi ayarlamak için hamcrest ve Google guice ile birlikte kullanıyorum .
Alay etmenin en iyi çözümü, makinenin tüm işleri otomatik spesifikasyon tabanlı testlerle yapmasını sağlamaktır. Java için, bkz. ScalaCheck ve İşlevsel Java kitaplığında bulunan Reductio çerçevesi . Otomatik spesifikasyon tabanlı test çerçeveleri ile test edilen yöntemin bir spesifikasyonunu sağlarsınız (bunun doğru olması gereken bir özellik) ve çerçeve otomatik olarak sahte nesnelerin yanı sıra testler de üretir.
Örneğin, aşağıdaki özellik Math.sqrt yöntemini test ederek n kare sayısının n değerinin karekökünün n'ye eşit olup olmadığını kontrol eder.
val propSqrt = forAll { (n: Int) => (n >= 0) ==> scala.Math.sqrt(n*n) == n }
Aradığınızda propSqrt.check()
, ScalaCheck yüzlerce tamsayı üretir ve her biri için mülkünüzü kontrol eder, ayrıca kenar durumlarının iyi bir şekilde kapandığından emin olur.
ScalaCheck Scala'da yazılmış ve Scala Derleyicisi gerektirse de, Java kodunu test etmek kolaydır. İşlevsel Java'daki Reductio çerçevesi, aynı kavramların saf bir Java uygulamasıdır.
Mockito ayrıca, stubbing yöntemleri, argümanları eşleştirme (anyInt () ve anyString () gibi), çağrı sayısını (times (3), atLeastOnce (), never ()) ve daha fazlasını doğrulama seçeneği sunar .
Mockito'nun basit ve temiz olduğunu da buldum .
Mockito hakkında sevmediğim bir şey, statik yöntemleri saplayamamanızdır .
Alayları JMock üzerinden kullanmaya başladım, ama sonunda EasyMock'u kullanmaya geçtim. EasyMock sadece - daha kolay-- ve daha doğal hissi veren bir sözdizimi sağlıyordu. O zamandan beri geçiş yapmadım.