Mock & stub arasındaki fark nedir?


963

Testte alaycılığa karşı stubbing ile ilgili çeşitli makaleler okudum, Martin Fowler's Mocks Stubs değil , ama yine de farkı anlamıyorum.



75
@OP Çünkü hiçbir fark yok. Bu makale, topluluk tarafından sevildiği kadar - tüm saygıyla - aksi takdirde anlaşılması kolay kelimelere ek anlamlar ekleyerek ve işleri karmaşık hale getirerek, her şeyi gereksiz kılmaktır. Sahte sadece bir sahte, gerçek yerine sahte iş mantığı çalıştıran bir şey. Sonunda davranışları kontrol etmek senin seçimin, ama yine de bir alay. Ya da ne demek istersen, ama BİR yap. Bir kılları bölmeyin. Basit tutun, böylece insanlar konseptinizi kolayca anlayabilir - yukarıdaki makalede başarısız olur.
WST

10
"Alay, sahte ve taslaklar arasındaki sınıflandırma literatürde oldukça tutarsız." Birçok alıntı ile. Hala en sevdiğim Wikipedia alıntılarından biri - eğer böyle bir şey varsa :) en.wikipedia.org/wiki/Mock_object
JD.

11
Martin Fowler'in makalesini yeni başlayanlar için anlamak gerçekten zor.
lmiguelvargasf

1
Anladığım kadarıyla, bir saplama, kukla verilerin toplanması gibi, testiniz için sadece bir atma nesnesi olacaktır. Alay, testleriniz için davranışını değiştirmiş olabileceğiniz çeşitli yöntemlere sahip bir hizmet katmanı gibi daha karmaşık bir şeyin akıllıca geçersiz kılınmış bir versiyonu olacaktır. İki şey birlikte kullanılır, sanki bazı kirli nesneleri alaycı katmanınıza geçirebilirsiniz.
JsonStatham

Yanıtlar:


746

Taslak

En büyük ayrımın, önceden belirlenmiş davranışlarla önceden yazdığınız bir saplama olduğuna inanıyorum. Bu nedenle, test amacıyla taklit ettiğiniz bağımlılığı (büyük olasılıkla soyut sınıf veya arayüz) uygulayan bir sınıfınız olur ve yöntemler yalnızca ayarlanmış yanıtlarla saplanır. Onlar fantezi bir şey yapmak olmaz ve zaten testin dışında bunun için stubbed kodu yazmış olurdu.

sahte

Bir alay, testinizin bir parçası olarak beklentilerinizle kurmanız gereken bir şeydir. Bir alay önceden belirlenmiş bir şekilde kurulmaz, bu yüzden testinizde bunu yapan bir kod vardır. Bir şekilde alaylar, beklentileri belirleyen kodun herhangi bir şey yapmadan önce çalışması gerektiğinden çalışma zamanında belirlenir.

Mocks ve Stubs arasındaki fark

Alaylarla yazılmış testler genellikle initialize -> set expectations -> exercise -> verifytest için bir model izler . Önceden yazılmış saplama bir initialize -> exercise -> verify.

Mocks ve Stubs arasındaki benzerlik

Her ikisinin de amacı, bir sınıfın veya işlevin tüm bağımlılıklarını sınamaktır, böylece testleriniz kanıtlamaya çalıştıkları şeylere daha odaklanmış ve basittir.


876

Önsöz

Gerçek olmayan nesnelerin birkaç tanımı vardır. Genel terim test çiftidir . Bu terim şunları içerir: kukla , sahte , saplama , sahte .

Referans

Göre Martin Fowler makalesinde :

  • Kukla nesneler geçer ama asla kullanılmaz. Genellikle sadece parametre listelerini doldurmak için kullanılırlar.
  • Sahte nesnelerin aslında çalışma uygulamaları vardır, ancak genellikle üretime uygun olmayan bazı kısayollar alırlar (bir bellek veritabanında iyi bir örnektir).
  • Saplamalar , test sırasında yapılan çağrılara, genellikle test için programlananların dışındaki hiçbir şeye cevap vermeyecek hazır yanıtlar sağlar. Saplamalar ayrıca, 'gönderdiği' mesajları hatırlayan bir e-posta ağ geçidi saplaması veya belki de yalnızca kaç mesaj gönderdiğini gibi aramalarla ilgili bilgileri de kaydedebilir.
  • Alaylar burada bahsettiğimiz şeydir: beklentileri ile önceden programlanmış nesneler, almaları beklenen çağrıların bir özelliğini oluşturur.

stil

Mocks vs Stubs = Davranışsal test vs Devlet testi

Prensip

Test ilkesine göre, test başına sadece bir şey , bir testte birkaç saplama olabilir, ancak genellikle sadece bir sahte vardır.

Yaşam döngüsü

Yaşam döngüsünü saplamalarla test edin:

  1. Kurulum - Test edilen nesneyi ve saplama ortaklarını hazırlayın.
  2. Egzersiz - İşlevi test edin.
  3. Durumu doğrula - Nesnenin durumunu kontrol etmek için ekleri kullanın.
  4. Teardown - Kaynakları temizleyin.

Yaşam döngüsünü alaylarla test edin:

  1. Kurulum verileri - Test edilen nesneyi hazırlayın.
  2. Kurulum beklentileri - Birincil nesne tarafından kullanılan sahte beklentileri hazırlayın.
  3. Egzersiz - İşlevi test edin.
  4. Beklentileri doğrulayın - Sahte yöntemlerde doğru yöntemlerin çağrıldığını doğrulayın.
  5. Durumu doğrula - Nesnenin durumunu kontrol etmek için ekleri kullanın.
  6. Teardown - Kaynakları temizleyin.

özet

Hem sahte hem de saplama testi şu soruya cevap verir: Sonuç nedir?

Alaylarla test yapmak da ilgilendi: Sonuç nasıl elde edildi?


Bekle, alaylar da hazır cevaplar verir mi? Aksi halde neden soruyu cevaplıyorlar?
AturSams

Yazdıklarınızdan, alayların = saplamalar + beklentiler ve doğrulamalar olduğunu söyleyebilirim, çünkü alaylar "test sırasında yapılan çağrılara, genellikle test için programlananların dışında hiçbir şeye cevap vermeyecek konserve cevaplar sağlar" (saplamalar gibi). Ve Fowler'ın bir saplama örneği olarak gösterdiği örnek aslında bir casus örneğidir! Bu, bir sahte bir saplama ve bir casusun bir saplama olduğu anlamına gelir. Ve bir saplama sadece birkaç çalışma yöntemine sahip bir nesnedir. Bu da Mockito'nun stub () yöntemini neden reddettiğini açıklıyor.
kolobok

Bu konuda kafa karıştırıcı bulduğum şey ve kabul edilen cevap bu “beklenti ayarı”, bu ne anlama geliyor? Genellikle, “ana kod” da beklediğiniz sonuçları yaratırsınız. Öyle görünüyor ki, beklentileri bir şekilde sahte nesneye soktunuz, ki bu bana mantıklı gelmiyor. AYRICA, sahte bir girişle kolayca egzersiz yapabilir, sonucu saklayabilir, daha sonra “beklentiler” oluşturabilir ve sonra karşılaştırabilirsiniz. Çok soyut ve belirsiz bulduğum terminolojiyi kullanıyorsunuz.
IceFire

365

Bir saplama basit bir sahte nesnedir. Sadece testin sorunsuz çalışmasını sağlar.
Bir alay daha akıllı bir saplamadır. Testinizin içinden geçtiğini doğrularsınız.


33
Bence bu cevapta en kısa ve öz. Paket servisi olan restoran: Sahte bir IS-A saplaması. stackoverflow.com/a/17810004/2288628 bu yanıtın daha uzun sürümüdür.
PoweredByRice

8
Sahte bir saplama olduğunu sanmıyorum. Alaylar iddia etmek için kullanılır ve asla veri döndürmemelidir, saplamalar veri döndürmek için kullanılır ve asla önermemelidir.
dave1010

2
@ dave1010 Alaylar kesinlikle veri döndürebilir ve hatta bir istisna atabilir. Bunu, kendilerine geçen paramlere yanıt olarak yapmalıdırlar.
Trenton

2
@trenton, bir nesne iletilen verilere dayanarak geri döner veya atarsa , sahte değildir, sahte olur. Stubs , SUT'unuzun mesajları almayı nasıl işlediğini , alaylar SUT'unuzun nasıl mesaj gönderdiğini test eder . 2'nin karıştırılması muhtemelen kötü OO tasarımına yol açacaktır.
dave1010

8
Bunun harika olduğunu düşünüyorum - bir saplama soruların cevaplarını döndürür. Bir sahte de soruların cevaplarını döndürür (is-a stub) ama aynı zamanda sorunun sorulduğunu da doğrular !!
Leif

238

İşte her birinin bir açıklaması ve ardından gerçek dünya örneği.

  • Kukla - karşılamak için sadece sahte değerleri API.

    Örnek : Bir yapıcıda , testiniz üzerinde etkisi olmayan birçok zorunlu parametre gerektiren bir sınıf yöntemini test ediyorsanız, bir sınıfın yeni örneklerini oluşturmak amacıyla kukla nesneler oluşturabilirsiniz.

  • Sahte - bazı harici altyapılara bağımlı olabilecek bir sınıfın test uygulamasını oluşturun. (Birim testinizin aslında dış altyapı ile etkileşime girmemesi iyi bir uygulamadır .)

    Örnek : Bir veritabanına erişmek için sahte uygulama oluşturun, in-memorykoleksiyonla değiştirin .

  • Saplama - Sabit kodlanmış değerleri döndürmek için geçersiz kılma yöntemlerini geçersiz kılar state-based.

    Örnek : Test sınıfınızın Calculate()tamamlanması 5 dakika süren bir yönteme bağlıdır . 5 dakika beklemek yerine, gerçek uygulamasını sabit kodlanmış değerleri döndüren saplama ile değiştirebilirsiniz; zamanın sadece küçük bir kısmını alıyor.

  • Sahte - devlete çok benzer Stubama interaction-baseddevlet temelli. Bu, bir Mockdeğer döndürmeyi beklemediğiniz anlamına gelir , ancak belirli yöntem çağrıları sırasının yapıldığını varsayarsınız.

    Örnek: Bir kullanıcı kayıt sınıfını test ediyorsunuz. Aradıktan sonra Savearamalı SendConfirmationEmail.

Stubsve Mocksaslında Mockher ikisi de test uygulamasıyla gerçek uygulamanın yerini, ancak farklı nedenlerle alt türleridir .


175

In codeschool.com kursu, Raylar Test Zombies için , onlar terimlerin bu tanımı vermektedir:

Taslak

Bir yöntemi, belirtilen sonucu döndüren kodla değiştirmek için.

sahte

Yöntemin çağrıldığı iddiası olan bir saplama.

Sean Copenhaver'ın cevabında açıkladığı gibi, fark, alaycıların beklentileri belirlemesi (yani çağrılıp çağrılmayacağı veya nasıl çağrılacağına dair iddialarda bulunmaları).


Dillon postasını tamamlamak için bunu düşünün, birkaç kitaplık alan "MakeACake" adlı bir Sınıfınız var: Süt, Yumurta, Şeker, Fırın.
aarkerio

139

Saplamalar testlerinizi geçemez, sahte olabilir.


2
Ve bence bu iyi, testlerin yeniden düzenleme sonrasında aynı davranışa sahip olup olmadığını biliyorsunuz.
RodriKing

1
@RodriKing Aynı hislerim var. Mock'ta olduğu gibi, üretim kodunda herhangi bir değişiklik olduğunda - test kodunda ilgili değişiklikleriniz var. Hangisi acıdır! Stubs ile, davranışı test etmeye devam ediyormuş gibi hissedersiniz, bu nedenle test koduyla mikro değişiklik yapılmasına gerek yoktur.
tucq88

35

Bu soru hakkındaki en basit ve net cevabın Roy Osherove tarafından “Unit Testing Art” (Birim Testi Sanatı ) adlı kitabında verildiğini düşünüyorum (sayfa 85)

Bir saplama ile uğraştığımızı söylemenin en kolay yolu, saplamanın hiçbir zaman testi geçemediğini fark etmektir. Test kullanımlarının her zaman test edilen sınıfa karşı olduğu varsayılır.

Öte yandan, test, testin başarısız olup olmadığını doğrulamak için bir sahte nesne kullanır. [...]

Yine, sahte nesne testin başarısız olup olmadığını görmek için kullandığımız nesnedir.

Bu, sahte aleyhte iddialarda bulunuyorsanız, sahte olanı sahte olarak kullandığınız anlamına gelir, sahte olanı sadece testi iddia etmeden çalıştırmak için kullanıyorsanız, sahte bir saplama olarak kullanırsınız.


2
Keşke cevabın zirveye ulaşabilirse. İşte R. Osherove bunu youtu.be/fAb_OnooCsQ?t=1006 açıklıyor .
Michael Ekoka

31

Yukarıdaki tüm açıklamaları okurken, yoğunlaşmaya çalışalım:

  • Stub : testin yapılmasına izin veren sahte bir kod parçası, ancak buna ne olduğu umurumda değil.
  • Mock : Testin bir parçası olarak DOĞRULANDIĞINIZ sahte bir kod parçası.
  • Casus : Gerçek bir kod parçasına yapılan bazı çağrıları engelleyen ve orijinal nesnenin tamamını değiştirmeden çağrıları doğrulamanızı sağlayan sahte bir kod parçası.

4
İyi cevap. Mock, tanımınıza bağlı olarak Spy'a oldukça benziyor. Cevabınızı birkaç test katına daha ekleyecek şekilde güncellerseniz iyi olur.
Rowan Gontier

Bu cevabı yazdığımda Spy'ı duymamıştım.
O'Rooney

23

Alay, sadece belirli yöntemlerin çağrıldığından emin olarak davranışı test ediyor. Saplama, belirli bir nesnenin test edilebilir bir sürümüdür (kendi başına).

Apple tarzı ne demek istiyorsun?


19
"Apple tarzı ne demek istiyorsun?" Helvetica kullanın
kubi

7
Bir Apple yolunda değil, Microsoft yolunda :)
never_had_a_name

2
Bu duruma yardımcı oluyor mu?
NebulaFox

21

Hata ayıklama ile karşılaştırırsanız:

Saplama , bir yöntemin doğru değeri döndürdüğünden emin olmak gibidir

Sahte aslında yönteme adım atmak ve doğru değeri döndürmeden önce içerideki her şeyin doğru olduğundan emin olmak gibidir.


20

Zihinsel bir model kullanma gerçekten "batmayan" açıklamaların ve makalelerin hepsinden ziyade bunu anlamama yardımcı oldu.

Çocuğunuzun masada bir cam tabağı olduğunu ve onunla oynamaya başladığını düşünün. Şimdi, kırılacağından korkuyorsun. Onun yerine ona plastik bir tabak veriyorsunuz. Bu bir sahte olurdu (aynı davranış, aynı arayüz, "daha yumuşak" uygulama) .

Şimdi, plastik yerine sahip olmadığınızı söyleyin, bu yüzden "Onunla oynamaya devam ederseniz, kırılacak!" Bu bir Saplama , önceden önceden tanımlanmış bir durum sağladınız.

Bir Dummy bile kullanmadığı çatal olurdu ... ve bir Spy zaten kullandığınız aynı açıklamayı sağlamak gibi bir şey olabilir.


19

Bence aralarındaki en önemli fark niyetleri.

Niçin saplama ve NEDEN sahte olarak açıklamaya çalışalım

Mac twitter istemcimin genel zaman çizelgesi denetleyicisine test kodu yazdığımı varsayalım

İşte test örnek kodu

twitter_api.stub(:public_timeline).and_return(public_timeline_array)
client_ui.should_receive(:insert_timeline_above).with(public_timeline_array)
controller.refresh_public_timeline
  • STUB: Twitter API'sına ağ bağlantısı çok yavaş, bu da testimi yavaşlatıyor. Zaman çizelgeleri döndüreceğini biliyorum, bu yüzden testimi çok hızlı çalıştıracak şekilde HTTP twitter API'sini simüle eden bir saplama yaptım ve çevrimdışı olduğumda bile testi çalıştırabilirim.
  • MOCK: Kullanıcı arabirimi yöntemlerimin hiçbirini henüz yazmadım ve kullanıcı arabirimi nesnem için hangi yöntemleri yazmam gerektiğinden emin değilim. Test kodunu yazarak kontrol cihazımın kullanıcı arayüzü nesnesiyle nasıl işbirliği yapacağını bilmeyi umuyorum.

Sahte yazarak, beklemenin karşılandığını doğrulayarak nesnelerin işbirliği ilişkisini keşfederken, saplama yalnızca nesnenin davranışını simüle eder.

Sahte ürünler hakkında daha fazla bilgi edinmek istiyorsanız bu makaleyi okumanızı öneririz: http://jmock.org/oopsla2004.pdf


1
Sanırım doğru fikre sahipsiniz, ama Dillon Kearns bunu çok daha açık bir şekilde açıkladı.
O'Rooney

19

Çok açık ve pratik olmak için:

Saplama: Taklit edilecek sınıf / nesne yöntemlerini uygulayan ve her zaman istediğinizi döndüren bir sınıf veya nesne.

JavaScript'teki örnek:

var Stub = {
   method_a: function(param_a, param_b){
      return 'This is an static result';
   }
}

Mock: Saplama ile aynıdır, ancak bir yöntem çağrıldığında "doğrulayan" bir mantık ekler, böylece bazı uygulamaların bu yöntemi çağırdığından emin olabilirsiniz.

@MLevan'ın dediği gibi bir örnek olarak bir kullanıcı kayıt sınıfını test ettiğinizi düşünün. Kaydet'i çağırdıktan sonra SendConfirmationEmail'i çağırmalıdır.

Çok aptal bir kod Örnek:

var Mock = {
   calls: {
      method_a: 0
   }

   method_a: function(param_a, param_b){
     this.method_a++; 
     console.log('Mock.method_a its been called!');
   }
}

16

Bu slayt temel farklılıkları çok iyi açıklıyor.

resim açıklamasını buraya girin

* CSE 403 Ders 16'dan, Washington Üniversitesi ("Marty Stepp" tarafından oluşturulan slayt)


Bu, iki IMO arasındaki farkın daha açık bir açıklamasıdır. Saplama için: test cihazı Saplamayı alır ve doğrudan test edilen sınıfın içinde kullanır. Ancak Mock için, test cihazının Mock nesnesinin nasıl kullanılacağını cihaz olarak kullanması gerekir. Farklı durumlarda, farklı davranacaktır. Bunun aksine, saplamanın farklı davranması beklenmez, ancak olduğu gibi kullanılır (her iletişim kurduğunda aynı verileri döndürmek anlamına gelir)
Dexter

12

Roy Osherove [video bağlantısı] tarafından yapılan açıklama hoşuma gitti .

Oluşturulan her sınıf veya nesne Sahte'dir. Çağrıları ona karşı doğrularsanız bu bir Mock'tur. Aksi takdirde onun bir saplama.


12
  • Stubs vs. Mocks
    • koçanları
      1. yöntem çağrılarına özel cevaplar sağlama
        • ex: myStubbedService.getValues ​​() sadece test edilen kodun gerektirdiği bir String döndürür
      2. test edilen kod tarafından izole etmek için kullanılır
      3. test başarısız olamaz
        • ex: myStubbedService.getValues ​​() sadece saplanan değeri döndürür
      4. genellikle soyut yöntemleri uygular
    • Mocks
      1. taslakların "üst kümesi"; belirli yöntemlerin çağrıldığını söyleyebilir
        • örnek: myMockedService.getValues ​​() işlevinin yalnızca bir kez çağrıldığını doğrulayın
      2. test edilen kodun davranışını test etmek için kullanılır
      3. test başarısız olabilir
        • ör .: myMockedService.getValues ​​() öğesinin bir kez çağrıldığını doğrulayın; myMockedService.getValues ​​() test edilen kodum tarafından çağrılmadığından doğrulama başarısız oluyor
      4. genellikle arayüzleri taklit eder

11

Test Çiftlerini görelim:

  • Sahte : Sahteler, çalışma uygulamaları olan, ancak üretim ile aynı olmayan nesnelerdir. Örneğin : Veri Erişim Nesnesi veya Deposunun bellek içi uygulaması.
  • Saplama : Saplama, önceden tanımlanmış verileri tutan ve testler sırasında çağrıları yanıtlamak için kullanan bir nesnedir. Örneğin : bir yöntem çağrısına yanıt vermek için veritabanından bazı verileri alması gereken bir nesne.

  • Alaycılar : Alaylar aldıkları aramaları kaydeden nesnelerdir. Test iddiasında, Mocks'ta beklenen tüm eylemlerin gerçekleştirildiğini doğrulayabiliriz. Örneğin : e-posta gönderme servisini çağıran bir işlev. daha fazlası için bunu kontrol edin .


1
Bence en iyi cevap
Ero Stefano

9

bir sahte gerçek bir nesne gibi çünkü onlar hem görünüm, bir saplama veya sahte bir nesne (el yazısı veya başka bir şekilde) ya betimlemek için kullanılabilir genel bir terimdir.

Sahte bir saplama veya alay olup olmadığı mevcut testte nasıl kullanıldığına bağlıdır. Bir etkileşimi kontrol etmek için kullanılırsa (karşı iddia edilir), bu sahte bir nesnedir. Aksi takdirde, bir saplamadır.

Sahte testin sorunsuz çalışmasını sağlar. Bu, gelecekteki testinizin okuyucusunun, kaynak kodunu okumak zorunda kalmadan (harici kaynağa bağlı kalmadan) sahte nesnenin davranışının ne olacağını anlayacağı anlamına gelir.

Test çalışması sorunsuz bir şekilde ne anlama geliyor?
Aşağıdaki kodda Forexample:

 public void Analyze(string filename)
        {
            if(filename.Length<8)
            {
                try
                {
                    errorService.LogError("long file entered named:" + filename);
                }
                catch (Exception e)
                {
                    mailService.SendEMail("admin@hotmail.com", "ErrorOnWebService", "someerror");
                }
            }
        }

Test yönteminizde bir Özel Durum simüle etmeniz için mailService.SendEMail () yöntemini test etmek istiyorsunuz , bu nedenle bu sonucu simüle etmek için bir Fake Stub errorService sınıfı oluşturmanız yeterlidir, daha sonra test kodunuz test edebilecektir. mailService.SendEMail () yöntemi. Gördüğünüz gibi, başka bir Harici Bağımlılık ErrorService sınıfından bir sonucu simüle etmeniz gerekir.


8

Sağ kağıttan Mock Rolleri, değil Nesneleri , JMock geliştiriciler tarafından:

Saplamalar, hazır sonuçları döndüren üretim kodunun kukla uygulamalarıdır. Sahte Nesneler taslak görevi görür, ancak aynı zamanda hedef nesnenin komşularıyla etkileşimlerini göstermek için iddiaları da içerir.

Yani, ana farklar:

  • saplamalara konulan beklentiler genellikle jenerikken, alaylara konan beklentiler daha "akıllı" olabilir (örneğin, bunu ilk çağrıda, ikincisinde vb.).
  • koçanları esas olarak kullanılan SUT kurulum dolaylı girişler ise, mocks test etmek için kullanılabilir dolaylı giriş ve dolaylı SUT çıkışları.

Özetlemek gerekirse, aynı zamanda karmaşayı Fowler'in makale başlığından dağıtmaya çalışırken : alaylar taslaklardır, ancak sadece taslak değildirler .


1
bence haklısın, ama bu yüzden Fowler makalesi kafa karıştırıcı, makale başlığı "Alaylar Saplama Değil" ... ama onlar ?! ¯_ (ツ) _ / ¯
stonedauwg

@stonedauwg, gerçekten, konuşmanızı ve bir açıklama eklemek için görevimi düzenledim. Umarım bu biraz daha yardımcı olur.
Dimos

@stonedauwg, sahte bir saplama değildir, tıpkı bir dikdörtgen kare değildir. :)
seanriordan08

7

Birim Testi Sanatı'nı okuyordum ve aşağıdaki tanıma tökezledim:

Bir sahte gerçek bir nesne gibi çünkü onlar hem görünüm, bir saplama veya sahte bir nesne (el yazısı veya başka bir şekilde) ya betimlemek için kullanılabilir genel bir terimdir. Sahte bir saplama veya alay olup olmadığı mevcut testte nasıl kullanıldığına bağlıdır. bir etkileşimi kontrol etmek için kullanılırsa (iddia edilen), sahte bir nesnedir . Aksi takdirde, bir saplamadır .


5

UncleBob The Little Mocker'ın bu ilginç makalesine rastladım . Tüm terminolojiyi anlaşılması çok kolay bir şekilde açıklar, bu yüzden yeni başlayanlar için yararlıdır. Martin Fowlers makalesi özellikle benim gibi yeni başlayanlar için zor bir okuma.


4

Stub test yapmamıza yardımcı olur. Nasıl? Testin yapılmasına yardımcı olan değerler verir. Bu değerlerin kendisi gerçek değildir ve bu değerleri sadece testi çalıştırmak için oluşturduk. Örneğin, veritabanı tablosundaki değerlere benzer değerler vermek için bir HashMap oluşturuyoruz. Dolayısıyla, veritabanıyla doğrudan etkileşim kurmak yerine Hashmap ile etkileşime giriyoruz.

Sahte , testi çalıştıran sahte bir nesnedir. iddia ettiğimiz yer.


"Yani doğrudan veritabanı ile etkileşim yerine Hashmap ile etkileşim." ... çünkü Veritabanı Modülünü kodlamak için henüz vakti yoktu ve test kodunu saplama kullanmadan çalıştıramadık. Aksi takdirde aynı Hasmap bir sahte olurdu! sağ?
Boris Däppen

4

C # ve Moq çerçevesini kullanarak alaylara karşı saplamalar örneğine bakın. Moq, Stub için özel bir anahtar kelimeye sahip değildir, ancak stub'lar oluşturmak için Mock nesnesini de kullanabilirsiniz.

namespace UnitTestProject2
{
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Moq;
    [TestClass]
    public class UnitTest1
    {
        /// <summary>
        /// Test using Mock to Verify that GetNameWithPrefix method calls Repository GetName method "once" when Id is greater than Zero
        /// </summary>
        [TestMethod]
        public void GetNameWithPrefix_IdIsTwelve_GetNameCalledOnce()
        {
            // Arrange 
            var mockEntityRepository = new Mock<IEntityRepository>();
            mockEntityRepository.Setup(m => m.GetName(It.IsAny<int>()));

            var entity = new EntityClass(mockEntityRepository.Object);
            // Act 
            var name = entity.GetNameWithPrefix(12);
            // Assert
            mockEntityRepository.Verify(m => m.GetName(It.IsAny<int>()), Times.Once);
        }
        /// <summary>
        /// Test using Mock to Verify that GetNameWithPrefix method doesn't call Repository GetName method when Id is Zero
        /// </summary>
        [TestMethod]
        public void GetNameWithPrefix_IdIsZero_GetNameNeverCalled()
        {
            // Arrange 
            var mockEntityRepository = new Mock<IEntityRepository>();
            mockEntityRepository.Setup(m => m.GetName(It.IsAny<int>()));
            var entity = new EntityClass(mockEntityRepository.Object);
            // Act 
            var name = entity.GetNameWithPrefix(0);
            // Assert
            mockEntityRepository.Verify(m => m.GetName(It.IsAny<int>()), Times.Never);
        }
        /// <summary>
        /// Test using Stub to Verify that GetNameWithPrefix method returns Name with a Prefix
        /// </summary>
        [TestMethod]
        public void GetNameWithPrefix_IdIsTwelve_ReturnsNameWithPrefix()
        {
            // Arrange 
            var stubEntityRepository = new Mock<IEntityRepository>();
            stubEntityRepository.Setup(m => m.GetName(It.IsAny<int>()))
                .Returns("Stub");
            const string EXPECTED_NAME_WITH_PREFIX = "Mr. Stub";
            var entity = new EntityClass(stubEntityRepository.Object);
            // Act 
            var name = entity.GetNameWithPrefix(12);
            // Assert
            Assert.AreEqual(EXPECTED_NAME_WITH_PREFIX, name);
        }
    }
    public class EntityClass
    {
        private IEntityRepository _entityRepository;
        public EntityClass(IEntityRepository entityRepository)
        {
            this._entityRepository = entityRepository;
        }
        public string Name { get; set; }
        public string GetNameWithPrefix(int id)
        {
            string name = string.Empty;
            if (id > 0)
            {
                name = this._entityRepository.GetName(id);
            }
            return "Mr. " + name;
        }
    }
    public interface IEntityRepository
    {
        string GetName(int id);
    }
    public class EntityRepository:IEntityRepository
    {
        public string GetName(int id)
        {
            // Code to connect to DB and get name based on Id
            return "NameFromDb";
        }
    }
}

4

Stub ve Mock testi bakış açısı:

  • Stub , kullanıcı tarafından statik yolla, yani Stub uygulama kodunu yazarken yapılan kukla bir uygulamadır . Bu nedenle hizmet tanımını ve dinamik durumu işleyemez, Normalde bu JUnit çerçevesinde alaycı çerçeve kullanılmadan yapılır.

  • Mock da kukla bir uygulamadır ancak uygulanması Mockito gibi Mocking çerçevelerini kullanarak dinamik bir şekilde gerçekleştirilmiştir. Böylece koşul ve hizmet tanımını dinamik bir şekilde ele alabiliriz, yani ataklar çalışma zamanında koddan dinamik olarak oluşturulabilir. Yani sahte kullanarak Stubs dinamik olarak uygulayabilirsiniz.


3

Ayrıca yararlı cevaplar, Sub'lardan daha fazla Mock kullanmanın en güçlü noktalarından biri

[Ana kodun ona bağlı olduğu] ortak çalışan bizim kontrolümüz altında değilse (örn. Üçüncü taraf bir kütüphaneden),
Bu durumda, saplama, sahte olmaktan ziyade yazmak daha zordur .


2

Farklılıkları göstermek için cevabımda python örnekleri kullandım.

Stub - Stubbing, geliştirme yaşam döngüsünün başlarında sınıf yöntemlerini uygulamak için kullanılan bir yazılım geliştirme tekniğidir. Arayüzün sonlandırıldığı veya bilindiği ancak uygulamanın henüz bilinmediği veya sonlandırılmadığı bilinen bir arayüzün uygulanması için yer tutucular olarak yaygın olarak kullanılırlar. Saplamalarla başlıyorsunuz, bu sadece bir fonksiyonun tanımını yazdığınız ve gerçek kodu daha sonra için bırakacağınız anlamına gelir. Avantajı, yöntemleri unutmayacağınız ve tasarımınızı kodda görürken düşünmeye devam edebilmenizdir. Saplamanın kodunuzun diğer bölümleri tarafından hemen kullanılabilmesi için saplamanızın statik bir yanıt vermesini de sağlayabilirsiniz. Saplama nesneleri geçerli bir yanıt sağlar, ancak hangi girdiyi iletirseniz iletin, her zaman aynı yanıtı alırsınız:

class Foo(object):
    def bar1(self):
        pass

    def bar2(self):
        #or ...
        raise NotImplementedError

    def bar3(self):
        #or return dummy data
        return "Dummy Data"

sahte nesneler, sahte nesneler üzerinde belirli yöntemlerin çağrıldığını doğrular. Sahte nesneler, gerçek nesnelerin davranışını kontrollü bir şekilde taklit eden simüle edilmiş nesnelerdir. Genellikle başka bir nesnenin davranışını sınamak için bir sahte nesne oluşturur. Alaycılar, birim testi için kullanılamayan veya çok yetersiz olan kaynakları simüle etmemizi sağlar.

mymodule.py:

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)

test.py:

from mymodule import rm
import mock
import unittest

class RmTestCase(unittest.TestCase):
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os):
        rm("any path")
        # test that rm called os.remove with the right parameters
        mock_os.remove.assert_called_with("any path")

if __name__ == '__main__':
    unittest.main()

Bu, rm'yi çalıştıran ve çağrıldığı parametreyi ileri süren çok temel bir örnektir. Sahte, yalnızca burada gösterildiği gibi işlevlerle değil, nesnelerle de kullanılabilir ve ayrıca bir değer döndürebilirsiniz; böylece sahte bir nesne, test için bir saplamanın yerine kullanılabilir.

Unittest.mock hakkında daha fazlası bilgi için, python 2.x not dahil değildir, ancak pip yoluyla indirilebilen indirilebilir bir modüldür (pip install mock).

Roy Osherove'un "Birim Testi Sanatı" nı da okudum ve benzer bir kitabın Python ve Python örnekleri kullanılarak yazılmasının harika olacağını düşünüyorum. Eğer böyle bir kitap bilen varsa lütfen paylaşın. Şerefe :)


2

Saplama, test amacıyla yapılmış sahte bir nesnedir. Sahte, beklenen çağrıların etkin bir şekilde gerçekleşip gerçekleşmediğini kaydeden bir saplamadır.


2

Saplama, testler sırasında işlenmeyen istisnaları önlemek için kullanılan boş bir işlevdir:

function foo(){}

Sahte, testler sırasında işletim sistemi, çevre veya donanım bağımlılıklarından kaçınmak için kullanılan yapay bir işlevdir:

function foo(bar){ window = this; return window.toString(bar); }

İddialar ve devlet açısından:

  • Bir olay veya durum değişikliğinden önce alaylar iddia edilir
  • Saplamalar iddia edilmez, ilgili olmayan birimlerden kod yürütülmesini önlemek için bir olaydan önce durum sağlar
  • Casuslar taslaklar gibi kurulur, daha sonra bir olay veya durum değişikliğinden sonra iddia edilir
  • Sahteler iddia edilmez, devletten kaçınmak için kodlanmış bağımlılıkları olan bir olaydan sonra çalışırlar

Referanslar


2
Terimler sözlüğüne casus eklemek için +1. Ayrıca, "Casus alay gibi kurulum" demek değil "Casus saplama gibi kurulum"
demek


2

Bir alay hem teknik hem de işlevsel bir nesnedir.

Sahte teknik . Bayt kodu üretimi sayesinde gerçekten bir alay kütüphanesi (EasyMock, JMockit ve daha yakın zamanda Mockito bilinir) tarafından yaratılmıştır .
Sahte uygulama, bir yöntem çağrıldığında belirli bir değeri döndürmek için bir araç oluşturabileceğimiz şekilde üretilir , ancak aynı zamanda bir sahte yöntemin bazı belirli parametrelerle (sıkı kontrol) veya parametreler ( sıkı kontrol yok).

Bir sahte örnekleme:

@Mock Foo fooMock

Bir davranışı kaydetme:

when(fooMock.hello()).thenReturn("hello you!");

Bir çağrıyı doğrulama:

verify(fooMock).hello()

Bunlar açıkça Foo sınıfını / davranışını başlatmanın / geçersiz kılmanın doğal yolu değildir. Bu yüzden teknik bir yönü kastediyorum.

Ancak alay da işlevseldir çünkü SUT'tan izole etmemiz gereken sınıfın bir örneğidir. Ve üzerinde kayıtlı davranışlar varsa, SUT'ta bir saplama ile yaptığımız gibi kullanabiliriz.


Saplama sadece işlevsel bir nesnedir: SUT'tan ayırmamız gereken sınıfın bir örneğidir ve hepsi bu. Bu, hem saplama sınıfının hem de birim testlerimiz sırasında ihtiyaç duyulan tüm davranış armatürlerinin açıkça tanımlanması gerektiği anlamına gelir.
Örneğin saplamanın hello()sınıfın alt Foosınıfına (veya sahip olduğu arabirimini uygular) ve geçersiz kılması gerekir hello() :

public class HelloStub extends Hello{    
  public String hello { 
      return "hello you!"; 
  }
}

Başka bir test senaryosu başka bir değer döndürmesi gerektiriyorsa, dönüşü ayarlamak için muhtemelen genel bir yol tanımlamamız gerekir:

public class HelloStub extends Hello{    
  public HelloStub(String helloReturn){
       this.helloReturn = helloReturn;
  }
  public String hello { 
      return helloReturn; 
  }
}

Diğer senaryo: Eğer bir yan etki yöntemi (dönüş yok) vardı ve ben bu yöntemin çağrıldığını kontrol, ben muhtemelen bir boolean veya bir sayaç stub sınıfına kaç kez yöntem çağrıldı saymak için eklemeliydim.


Sonuç

Saplama, birim testiniz için yazmak için genellikle çok fazla ek yük / kod gerektirir. Kutudan çıkan kayıt / doğrulama özellikleri sayesinde alay eden şey önler.
Bu nedenle günümüzde saplama yaklaşımı, pratikte mükemmel sahte kütüphanelerin ortaya çıkmasıyla nadiren kullanılmaktadır.


Martin Fowler Hakkında Makale: Alaycı kullanırken "sahte" bir programcı olmayı düşünmüyorum ve taslaklardan kaçıyorum.
Ama gerçekten gerekli olduğunda sahte kullanıyorum (sinir bozucu bağımlılıklar) ve alaycı bir ek yük olacak bağımlılıkları olan bir sınıfı test ettiğimde test dilimleme ve mini entegrasyon testlerini tercih ediyorum.

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.