SORU
1 EYLÜL 2008, PAZARTESİ


Ne zaman alay edeyim?

Sahte ve sahte nesneler temel bir anlayış var, ama özellikle bu senaryo için here uygulamak gibi alaycı kullanımı hakkında hissediyorum emin değilim.

CEVAP
1 EYLÜL 2008, PAZARTESİ


Mock nesneler için istediğiniz zaman yararlıdırtest etkileşimleritest altında bir sınıf ve özel bir arayüz arasında.

Örneğin, istediğimiz için test yöntemi sendInvitations(MailServer mailServer) aramalar MailServer.createMessage() tam bir kez ve çağrıları MailServer.sendMessage(m) tam bir kez, ve başka bir yöntem olarak MailServer arabirim. Bu mock nesneleri kullanabiliriz.

Bir gerçek geçen MailServerImpl veya bir test yerine mock nesneler ile, TestMailServer, MailServer arabirim bir sahte uygulama geçirebiliriz. Bir alay MailServer, "tren", beklemek dediği şeyi bilen ve geri dönüş değerleri ne kadar. geçmeden önce ... Sonunda, alay nesnesinin tüm yöntemleri beklenen beklendiği gibi denirdi iddia.

Bu teoride kulağa hoş geliyor, ama aynı zamanda bazı dezavantajları da vardır.

Alay eksiklikleri

Eğer bir yerde sahte bir çerçeve varsa, sahte nesne kullanmak için cazip vardırher zamantest altında sınıfı için bir arayüz geçmesi gerekir. Bu sonunda yoltest gerekli değilken bile geçemezler. Ne yazık ki, etkileşimleri (yanlışlıkla) istenmeyen test sonra belirli bir gereği belirli bir şekilde uygulanır, yerine uygulanması gerekli sonucu üretilen test ediyorsunuz.

İşte yalancı bir örnek. Hadi MySorter bir sınıf oluşturduk varsayalım ve bunu test etmek istiyoruz:

// the correct way of testing
testSort() {
    testList = [1, 7, 3, 8, 2] 
    MySorter.sort(testList)

    assert testList equals [1, 2, 3, 7, 8]
}


// incorrect, testing implementation
testSort() {
    testList = [1, 7, 3, 8, 2] 
    MySorter.sort(testList)

    assert that compare(1, 2) was called once 
    assert that compare(1, 3) was not called 
    assert that compare(2, 3) was called once 
    ....
}

(Bu örnekte, belirli bir sıralama algoritması, hızlı sıralama gibi olmadığını, test etmek istediğimizi varsayalım; bu durumda, ikinci testin aslında geçerli olacaktır.)

Böyle uç bir örnek olarak ikinci örnek yanlış olduğunu neden açıktır. Ne zaman biz değiştirmek uygulanması MySorter ilk testi yapar büyük bir iş yapmak emin biz hala sıralama doğru, hangisi bütün mesele testleri - izin bize değiştirme kodu güvenli bir şekilde. Öte yandan, ikinci testher zamantatili ve aktif olarak zararlı olabilir; yeniden düzenleme engeller.

Koçanları gibi alay ediyor

Sahte çerçeveler genellikle izin de daha az katı kullanım, nerede bilmiyoruz belirtmek tam olarak kaç kez yöntem çağrılmalıdır ve ne parametreler beklenen; izin oluşturma mock nesneler kullanılan gibi stubs.

Hadi test etmek istediğimiz bir yöntem sendInvitations(PdfFormatter pdfFormatter, MailServer mailServer) diyebiliriz. PdfFormatter nesne davetiye oluşturmak için kullanılabilir. İşte test:

testInvitations() {
   // train as stub
   pdfFormatter = create mock of PdfFormatter
   let pdfFormatter.getCanvasWidth() returns 100
   let pdfFormatter.getCanvasHeight() returns 300
   let pdfFormatter.addText(x, y, text) returns true 
   let pdfFormatter.drawLine(line) does nothing

   // train as mock
   mailServer = create mock of MailServer
   expect mailServer.sendMail() called exactly once

   // do the test
   sendInvitations(pdfFormatter, mailServer)

   assert that all pdfFormatter expectations are met
   assert that all mailServer expectations are met
}

Bu örnekte, biz yok gerçekten bakımı hakkında PdfFormatter nesne sadece Tren için sessizce kabul herhangi bir çağrı ve geri dönüş biraz mantıklı konserve dönüş değerleri için tüm yöntemleri sendInvitation() olur arayıp bu noktada. Nasıl yöntemler tam olarak bu liste ile tren nereden geldi? Biz sadece test koştu ve testi geçti kadar yöntemleri ekleme tuttu. Saplama buna ihtiyacı neden hakkında hiçbir şey bilmeden bir yöntem cevap vermek için eğitilmiş dikkat edin, biz sadece test şikayetçi olan her şeyi ekledi. Mutluyuz, testi geçer.

Ama sendInvitations() sendInvitations() kullanan başka bir sınıf, daha güzel bir PDF oluşturmak için değiştirirsek ne olur sonra? Bizim test PdfFormatter şimdi daha çok bir yöntem olarak adlandırılır ve onları beklemek bizim saplama tren etmedik çünkü aniden başarısız olur. Ve bu gibi durumlarda başarısız sadece bir test değil genellikle, kullanmak için, doğrudan veya dolaylı olarak, sendInvitations() yöntemi oluşan bir test. Daha eğitimleri ekleyerek tüm bu testleri çözmek için var. Aynı zamanda gerekli olmayan bilmiyoruz çünkü yöntemleri artık gerekli kaldırın, yapamayız dikkat edin. Yine, yeniden düzenleme engeller.

Ayrıca, okunabilirliği test uğradığı korkunç, orada bir sürü kod olduğunu bilmiyorduk çünkü yazmak istedik, ama zorundaydık çünkü; bizi kim istiyor bu kodu. Mock nesneleri kullanan testler çok karmaşık bakmak ve sık sık okumak zor. Testler test sınıfı altında kullanılmalıdır nasıl anlamak okuyucu yardımcı olmalıdır, böylece basit ve anlaşılır olmalıdır. Eğer okunaklı değilse, hiç kimse onları korumak için gidiyor; aslında, onları korumak için daha onları silmek daha kolay oluyor.

Bunu nasıl düzeltebilirim? Kolay:

  • Mümkün olduğunda alay yerine gerçek sınıfları kullanmayı deneyin. Gerçek PdfFormatterImpl kullanın. Eğer bu mümkün değilse, gerçek sınıfları bunu mümkün kılmak için değiştirin. Testlerde bir sınıf kullanmak mümkün değil genelde sınıfı ile ilgili bazı sorunları işaret eder. Sorunları gidermek için bir kazan-kazan durumu - sınıfı sabit ve basit bir test var. Diğer taraftan, tamir ve alay kullanarak değil, hayır-kazan durumu - gerçek sınıf düzeltme gelmedi ve daha refactorings engel daha karmaşık, daha az okunabilir testleri var.
  • Arayüzü Basit bir test uygulaması oluşturmayı denemek yerine her testte alay, ve tüm testleri bu test sınıfı kullanın. Hiçbir şey yok TestPdfFormatter oluşturun. Bunu bir kez tüm testler ve testleri için değiştirebilirsiniz böylece senin taslakları, tren nerede uzun kurulumları ile darmadağın değildir.

Kullanımları var, ama dikkatlice kullanılmadığı zamangenellikle kötü uygulamalarını teşvik etmek, Uygulama Detayları test, çabasını engellemek ve okumaya ve bakımı zor testler üretmek.

Alay eksiklikleri hakkında biraz daha fazla ayrıntı için Mock Objects: Shortcomings and Use Cases Ayrıca Bkz.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Edge-CGI 3D Tutorials and more!

    Edge-CGI 3D

    11 HAZİRAN 2013
  • RogerBuckChrist

    RogerBuckChr

    9 Temmuz 2011
  • Virtual Riot

    Virtual Riot

    19 Mayıs 2011