2010-09-01 21 views
7

Bir yöntemin, özel bir argümanla tekrarlı olarak denendiğini test etmek isterim.Rspec: Yinelemeyi nasıl test edebilirim?

Benim yaklaşım:

expected :rec with (7) once, but received it 0 times 

benim yaklaşımla sorunun ne herhangi bir fikir: Beklenmedik

class Recursable 
    def rec(arg) 
    rec(7) unless arg == 7 
    end 
end 

describe Recursable do 
    it "should recurse" do 
    r = Recursable.new('test') 
    r.should_receive(:rec).with(0).ordered 
    r.should_receive(:rec).with(7).ordered 
    r.rec(0) 
    end 
end 

, RSpec ile başarısız? Belirli bir argüman ile etkili özyineleme testi nasıl yapılır?

cevap

10

Testinizdeki sorun şu an olduğu gibi test etmeye çalıştığınız yöntemi kaçırıyor olmanızdır. r.should_receive(:rec), r#rec'un yerine, r.rec(7) numaralı telefonu aramayan bir sapla değiştiriyor. İlk yöntem çağrısı sonucunun doğru olduğunu basitçe test etmek daha iyi bir yaklaşım olacaktır. Sonunda doğru cevabı verdiği sürece, yöntemin ister bir arkadaş isterse, bir arkadaşını tekrar edip etmediğini veya tekrar etmemesini kesinlikle bilmemelidir.

+0

Ah, tamam. Oh iyi! Bir hata bulmaya çalışıyorum - yöntem yanlış bir değer döndürüyor (burada betimlendiğinden daha karmaşıktır). Sorun alanını daraltmak için her parçasını test edebileceğimi düşündüm. Her bir yineleme seviyesi ile daha karmaşık hale gelir ve özyinenin doğru şekilde yürütülüp yürütülmediğini test etmek güzel olurdu. – crispy

+2

Başka bir deyişle: Uygulamayı test etmeyin, kodun etkisini test edin. Mükemmel cevap! – awendt

2

Çoğunlukla özyinelemeyi sınamanız gerekirse kod kokusu olur; Muhtemelen yöntemi farklı sorumluluklara veya başka bir şeye bölmelisiniz.

Ancak bazı durumlarda özyinenizde bazı temel kontrolleri eklemeniz yeterlidir. Sen RSpec and_call_original ile yapabilirsiniz: özyineleme çalışmıyor neden

it "should recurse" do 
    r = Recursable.new('test') 
    r.should_receive(:rec).with(0).ordered.and_call_original 
    r.should_receive(:rec).with(7).ordered.and_call_original 
    r.rec(0) 
end 

Normalde should_receive tıpkı gerçek yöntemini atacak, bu. and_call_original ile, stubbed yöntem (test kontrollerini içerir), aynı zamanda, yinelemeyi beklendiği gibi gerçekleştirecek orijinal yöntem uygulamasını da çağırır.