2013-07-29 14 views
5

FakeItEasy'yi kullanarak, nesnemin yönteminin aynı nesne üzerinde başka bir yöntem mi çağırdığını görmek için nasıl denetlerim?Aynı nesnedeki başka bir yöntemde FakeItEasy's A.CallTo() yöntemini kullan

Testi:

[TestMethod] 
public void EatBanana_CallsWillEat() 
{ 
    var banana = new Banana(); 
    var myMonkey = new Monkey(); 

    myMonkey.EatBanana(banana); 

    //this throws an ArgumentException, because myMonkey is a real instance, not a fake 
    A.CallTo(() => myMonkey.WillEat(banana) 
    .MustHaveHappened(); 
} 

Sınıf:

public class MyMonkey { 
    private readonly IMonkeyRepo _monkeyRepo; 

    public MyMonkey(IMonkeyRepo monkeyRepo) { 
    _monkeyRepo = monkeyRepo; 
    } 

    public void EatBanana(Banana banana) { 
    //make sure the monkey will eat the banana 
    if (!this.WillEat(banana)) { 
     return; 
    } 

    //do things here 
    } 

    public bool WillEat(Banana banana) { 
    return !banana.IsRotten; 
    } 
} 

Önerilere açığım. Eğer bu konuda yanlış gidersem, lütfen bana bildirin.

+2

Bu, FIE'nin anladığı gibi değil. FIE sahte nesneler sağlar, böylece üretim kodunuz daha kolay dürtülebilir ve üretilebilir. İşaret ettiğin gibi, sende sahte yok. Deneyimlerime göre, bu tür bir test genellikle iyi bir fikir değildir. MyMonkey sınıfınız kendi içinde yeterli bir birim olmalı ve kendi yöntemlerini denemekten endişe etmekten ziyade, bir muz yemeye karar verildiğinde genel davranışını test etmekten daha iyi olursunuz. Örneğin, muzun "burada işler yap" daki ipuçlarından yola çıkarak yediğini söyleyebilecek misiniz? –

+0

@BlairConrad benim gerçek senaryomda WillEat daha karmaşık ve kendi testleri var ve bu da EatBanana'nın sahip olduğu testlerden sadece biri. Bu testte, EatBanana'nın gerçek WillEat'ı aramasına izin verirsem, bir testte iki özelliği test etmeyecek miyim? Sonra, WillEat değiştiyse, bu testi bozabilir, bu kötü bir haber, değil mi? –

+4

Ben senin noktasını görüyorum. Bu zor. Eğer WillEat başka bir nesnede yaşarsa, hepimiz o nesneyi numaralandırmaya ve 'MyMonkey'e (acı verici sesler) enjekte etmeye çağırırız. Tüm söyleyebileceğim en iyi varsayılan pozisyonun, bir müşterinin gözlemlenebilir sonuçlarına dayanarak 'MyMonkey'i dışarıdan test etmeye çalışmak olduğunu düşünüyorum. Ancak, içine düşünce koydunuz ve size acıdan tasarruf edecek bir çözüm buldunuz ve test sayısını ve verilen verilere ayıracak sayıyı azaltıyor. En iyi kodu biliyorsunuz, bu yüzden eğer sizin için çalışıyorsa… Sadece alternatifin farkında olmanızı istedim. –

cevap

2

Bunu yapmak da mümkündür. WillEat yöntemi sanal ise - aksi halde FakeItEasy bunu başaramaz. O değişiklikle

, bunu yapabilirdi:

[TestMethod] 
public void EatBanana_CallsWillEat() 
{ 
    var fakeMonkey = A.Fake<MyMonkey>(); 

    fakeMonkey.EatBanana(new Banana()); 

    A.CallTo(()=>fakeMonkey.WillEat(A<Banana>._)).MustHaveHappened(); 
} 

Hala (Ben yorum ranted gibi) bunun iyi bir fikir olduğuna ikna olmuş değilim - ama, geçen güvenerek daha iyi olacağını düşünüyorum gözlemlenebilir davranış, ama sisteminize aşina değilim. Bunun en iyi yol olduğunu düşünüyorsanız, örnek kod sizin için çalışmalıdır.

3

Neden test edilen nesneyi alay ediyorsunuz? Ne tam olarak test etmeye çalışıyorsunuz? WillEat numaralı telefona yapılan doğrulama az değerlidir. Tüketiciye hangi bilgiler verilir? Sonuçta, tüketici yöntemin nasıl uygulandığını umursamıyor. Tüketici, neyin neyle ilgili olduğunu nolu sonuçlar.

Maymun muz yediğinde ne olur çürümüş değil? Düzgün sahte ve burada enjekte edilir IMonkeyRepo için doğrulamaları her tür yapabilirsiniz

[TestMethod] 
public void EatBanana_CAUSES_WHAT_WhenBananaIsNotRotten() 
{ 
    var repo = A.Fake<IMonkeyRepo>(); 
    var monkey = new Monkey(repo); 
    var freshBanana = new Banana { IsRotten = false }; 

    monkey.EatBanana(freshBanana); 

    // verifications here depend on what you expect from 
    // monkey eating fresh banana 
} 

Not: Sizin testi bu soruya cevap gerekir.

+0

İyi nokta. Eğer WillEat'la dalga geçmezsem ve EatBanana'nın gerçek WillEat'ı aramasına izin veriyorum, bir testte iki özelliği test ediyor muyum?Bu örnekte, WillEat önemsizdir, ama benim gerçek durumumda, daha karmaşıktır ve argümanlarına dayanarak türetilmiş bir nesneyi döndürür, bu yüzden alay ettiğimi anladım ve bunun doğru olduğunu söylemek doğru yolu seçti. Şu anda WillEat için ayrı testlerim var ve Repo'nun çağrıldığını doğrulamak da dahil olmak üzere, EatBanana için birkaç test daha yapıyor. Belki fazla granül oluyorum? –

+3

@JoshNoe: ya da yeterince granül yapmıyor olabilirsiniz. Eğer WillEat bu kadar karmaşıksa, belki kendi sınıfında yaşamalı mıdır? Belki de bu özelliği * gıda-değerlendirici-çeşit-şeyi * çıkarmak ve onu maymunlara enjekte etmek daha mantıklıdır? Testler * basit olmalıdır * eğer olmasalar bile * genellikle * tasarımın yeniden gözden geçirilebileceğinin iyi bir göstergesidir. Bir yan notta, neden '' Monkey' 'IMonkeyRepository'' bağımlı? –

İlgili konular