Web servis araması gerektiren bir sınıfı nasıl test edebilirim?


21

Bazı Hadoop web servislerini çağıran bir sınıfı test etmeye çalışıyorum. Kod formun hemen hemen:

method() {
    ...use Jersey client to create WebResource...
    ...make request...
    ...do something with response...
}

örneğin bir create directory yöntemi, bir create folder method vb. vardır.

Kodun üzerinde kontrolüm olmadığı harici bir web servisiyle ilgili olduğu göz önüne alındığında, bunu nasıl test edebilirim? Web hizmeti istemcisini / yanıtlarını deneyebilir ve alay edebilirim ancak bu son zamanlarda çokça gördüğüm kılavuza uymuyor: "Sahip olmadığınız nesnelerle dalga geçme". Sahte bir web servisi uygulaması kurabilirim - bu hala bir "birim testi" mi olurdu yoksa o zaman bir entegrasyon testi olur mu? Test seviyesini bu düşük seviyede birleştirmek mümkün değil midir? TDD uygulayıcısı bunun için nasıl devam eder?


5
Sahip olmadığınız şeylerle alay etmeme konusunda rehberlik nerede gördünüz? Bu şeyleri alay etmemeniz için büyük bir neden gibi görünüyor ...
Thomas Owens


1
@ChrisCooper: Son bağlantının çok eski olduğunu belirtebilir miyim (2007'den itibaren). O zamandan beri çok şey değişti. Sonrasında alaycılığın çok daha zor olduğu hissine kapıldım, o zaman geri dönüş değerleri oluşturmak için alaycı bir çerçeve ya da metaprogramlama kullanmak yerine, aslında davranışları uygulamak zorunda kaldığınızda ...
c_maker 11:13

Yanıtlar:


41

Bence, bu bir birim sınavıysa, bir entegrasyon sınavının aksine, web servis çağrıları ile alay etmelisiniz.

Birim testiniz, harici web servisinin çalışıp çalışmadığını veya bununla entegrasyonunuzun doğru olup olmadığını test etmemelidir. TDD hakkında fazla dogmatik olmadan, ünite testinizi bir entegrasyon testine dönüştürmenin bir yan etkisinin daha yavaş çalışmasının muhtemel olduğunu ve hızlı ünite testleri istediğinizi unutmayın .

Ayrıca, web servisi geçici olarak kapalıysa veya yanlış çalışıyorsa, bu durum birim testinizin başarısız olmasına neden olur mu? Doğru görünmüyor. Birim testiniz yalnızca bir nedenden ötürü başarısız olmalıdır: eğer bu "birim" deki kodda bir hata varsa.

Burada ilgili kodun tek kısmı ...do something with response.... Gerisini alay et.


2
Sahte nesne imzanızı saklamanız ve bu hizmette kaçınılmaz değişiklikler sırasında Hadoop web hizmeti tarafından oluşturulan değerlerle eşit değerleri döndürmeniz gerektiğini unutmayın.
pcurry 11:13

Hadoop gibi kullanıma hazır bileşenleri test etmeye nadiren değer. Ancak, başka bir ekip veya kuruluş tarafından sağlanan özel bir web servisini arıyorsanız, kendini savunma konusunda bir test yazmak isteyebilirsiniz. Bu şekilde işler ters gittiğinde, sorunun kodunuzun veya web servisinin olup olmadığını hızlıca kontrol edebilirsiniz. Bu otomatik olarak çalışacak bir ünite testi değildir; Gerektiği gibi çalıştırmak için bir tanı.
kevin cline

@kevincline Önerdiğiniz testlerin gerekliliği konusunda tamamen aynı fikirdeyim ve gerçekten onları günlük işime yazıyorum ve kendilerini faydalı olduklarını kanıtladım. Ancak bunlar tanım gereği DEĞİLDİR ünite testleri değil, sorunun konusu neydi :) :) Bunu göz önünde bulundurun: ünite testi ise ve web hizmeti değiştiği için kod başarısız olursa, test ettiğiniz "ünite" nedir? Tam olarak ne başarısız oldu? Ünite testlerinin gerektirdiği şekilde izolasyon testi yapmıyorsunuz.
Andres F.

1
@AndresF .: Şiddetli bir anlaşmaya vardığımızı düşünüyorum: "Bu [teşhis] bir birim testi değil ..."
kevin cline

@kevincline Right! Yorumunuzu yanlış okudum, üzgünüm!
Andres F.

5

Birim sınaması yaparken "sahip olmadığınız nesnelerle dalga geçme" ifadesine katılmıyorum.

Alayın amacı, sahip olamayacağımız modüller, kütüphaneler, sınıflar olacağı gerçeğidir.

Senaryo için önerim, web servis çağrısı ile alay etmektir.

Sahte veri modülünüze geri döndürecek şekilde ayarlayın.
Tüm senaryoları örttüğünüzden emin olun; örneğin, geri döndürülen veriler boş olduğunda, geri döndürülen veriler geçerliyse vb.

Ve sahip olduğunuz kod için, geliştirici olarak sizin sorumluluğunuz, geliştirdiğiniz kodun tüm senaryolarda beklendiği gibi çalışmasını sağlamaktır.


1

Bu test için EasyMock gibi bir şey kullanırdım. Alaycı çerçeveler bir sınıfa dış bağımlılıkları kaldırmak için ideal bir yoldur ve testler sırasında dış bağımlılıkların sonucu üzerinde tam kontrol sağlar. Örneğinizi biraz uzatmak için:

class WebClass {

private WebServiceInterface webserviceInterface;

    void method(){
        R result = webServiceInterface.performWebServiceCall();
        ... do something with result
    }

    public void setWebServiceInterface(WebServiceInterface webServiceInterface){
        this.webServiceInterface = webServiceInterface;
    }
}


interface WebServiceInterface {

   R performWebServiceCall();

}


class WebClassTest {

private WebServiceInterface mock;    
private R sampleResult = new R();

    @Before
    public void before(){
        mock = EasyMock.createMock(WebServiceInterface.class);
    }


    @Test
    public void test() {
        WebClass classUnderTest = new WebClass();
        EasyMock.expect(mock.performWebServiceCall()).andReturn(sampleResult);
        classUnderTest.setWebServiceInterface(mock);
        classUnderTest.method();
        EasyMock.verify(mock);
    }
}

Yapmanız gereken ilk şey, bir WebResource'u almak ve web hizmetini ayrı bir sınıfa çağırmak için Jersey'i kullandığınız sınıftaki mantığı çıkarmaktır. Bu sınıf için bir Arayüz oluşturmak, daha sonra davranış dikte edebileceğiniz bir alay oluşturmanıza olanak sağlar.

Bu arayüz oluşturulduktan sonra, test durumunuza göre belirli bir nesneyi döndürecek EasyMock'u kullanarak bir sahte oluşturabilirsiniz. Yukarıdaki örnek, temel bir alay testinin nasıl yapılandırılacağının ve arayüzünüzün nasıl çalışacağının basitleştirilmesidir.

Alaycı çerçeveler hakkında daha fazla bilgi için, lütfen bu soruya bakın . Ayrıca, bu örnekte Java kullanımı varsayılmaktadır ancak alaycı çerçeveler tüm dillerde mevcuttur ve farklı şekilde uygulanmasına rağmen, genel olarak aynı şekilde çalışacaklardır.


1

Bu durumda alay kabul edilebilir, ancak buna ihtiyacınız yok. Ünite testi yerine, ünite testi method()yerine yanıtı sağlayan kısmı test edin.

ResponseData(Hangi türden olursa olsun) alan bir işlevi ayıklayın ve ardından işlemi gerçekleştirin.

Alay etmek yerine, şimdi sadece bir ResponseData nesnesi oluşturup içeri aktarıyorsunuz.

Sen bırakabilir çağırarak tam entegrasyon testlerinin hizmet - yani kapsayacak method()toplamda


0

Ne yaptım ve işe yarıyor:

  1. Tüm kodların web servislerini proxy üzerinden çağırın
  2. Proxy, proxy kullanıp kullanmadığımızı ve buna göre yönlendirenleri statik olarak bilen bir sınıfı çağırır. Alaylar, her istek için verilen bir cevabı döndüren sadece HashMaps'tir.
  3. Bu sırayla testleri birkaç kez çalıştırın:

3.1 İlk önce tüm web servisleri test edilir. Her makineden, hatta geliştiricinin makineleri. Bunlar gerçek web servisleridir ancak geliştirme ortamlarında çalışmaktadır. Bu, web servislerinin asla hatalı olamayacağı veya yanlış değerlere cevap veremeyeceği anlamına gelir, çünkü aksi takdirde her geliştirici derleyemediğinden şikayet eder.

3.2 Ardından, uygulamanın içindeki tüm birim testleri gerçekleştirilir. Bu, tüm web servislerinin, aynı testlerle 3.1 (aynı zamanda geçmeleri gerekir, aksi halde sahtedirler) çalıştırılarak ve gerçekten kullanılıyormuş gibi gerçek uygulama tarafından çağrıldığı anlamına gelir. Sahiller yanlışsa, testi 3.1'de çalıştırabilir ve bu (istek, cevap) değerlerini bir HashMap'te kaydedebilirsiniz.

3.3 Ardından 3.2 ile aynı testler yapılır, ancak bu kez geliştirme ortamında çalışan gerçek web servislerine karşı.

Tüm bunlar tamamlandıktan sonra, gerçek üretim ortamı için her web hizmeti için gerçek adresi sağlamanız yeterlidir. Umarım bu yapılandırmada çok fazla değişiklik gerektirmez.

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.