2012-12-22 15 views
5

, ben değeri geçerli bir değerler listesi içinde olduğunu garanti etmek belirli bir alanda (Kullanıcı modelinde rol) davranışını kontrol eden bir RSpec spec var.Yeniden kullanım RSpec davranış doğrulama

Şimdi başka bir alan için başka bir modelde, başka bir geçerli değer grubuyla aynı spesifikliğe sahip olacağım. Değişkenleri değiştirip kopyalayıp yapıştırmak yerine ortak kodu çıkarmak istiyorum.

paylaşılan örnek veya başka bir RSpec yeniden kullanım tekniğinin kullanılması durumunun mümkün olup olmadığını merak ediyorum. İşte

ilgili RSpec kod:

describe "validation" do 
    describe "#role" do 
    context "with a valid role value" do 
     it "is valid" do 
     User::ROLES.each do |role| 
      build(:user, :role => role).should be_valid 
     end 
     end 
    end 

    context "with an empty role" do 
     subject { build(:user, :role => nil) } 

     it "is invalid" do 
     subject.should_not be_valid 
     end 

     it "adds an error message for the role" do 
     subject.save.should be_false 
     subject.errors.messages[:role].first.should == "can't be blank" 
     end 
    end 

    context "with an invalid role value" do 
     subject { build(:user, :role => 'unknown') } 

     it "is invalid" do 
     subject.should_not be_valid 
     end 

     it "adds an error message for the role" do 
     subject.save.should be_false 
     subject.errors.messages[:role].first.should =~ /unknown isn't a valid role/ 
     end 
    end 
    end 
end 

iyi bu kodu yeniden dava, ancak rol (alan onaylanmamaktadır) ve Kullanıcının :: ROLLERİ (toplanmasını ayıklanması ne olurdu geçerli değerler) bu koda geçirilen parametreler? Birkaç specs..I çok fazla olduğunu düşünüyorum KURU Fikriniz

shared_examples "no role" do 
    it "is invalid" do 
     subject.should_not be_valid 
    end 
    end 

    context "with an empty role" do 
    subject { Factory.build(:user, :name => nil) } 
    it_behaves_like "no role" 
    end 

    context "with an invalid role value" do 
    subject { Factory.build(:user, :name => '') } 
    it_behaves_like "no role" 
    end 

Ama ne:

cevap

2

Bu, paylaşılan örnekler için mükemmel bir makul kullanım durumu olduğunu düşünüyorum. Örneğin. Böyle bir şey:

shared_examples_for "attribute in collection" do |attr_name, valid_values| 

    context "with a valid role value" do 
    it "is valid" do 
     valid_values.each do |role| 
     build(:user, attr_name => role).should be_valid 
     end 
    end 
    end 

    context "with an empty #{attr_name}" do 
    subject { build(:user, attr_name => nil) } 

    it "is invalid" do 
     subject.should_not be_valid 
    end 

    it "adds an error message for the #{attr_name}" do 
     subject.save.should be_false 
     subject.errors.messages[attr_name].first.should == "can't be blank" 
    end 
    end 

    context "with an invalid #{attr_name} value" do 
    subject { build(:user, attr_name => 'unknown') } 

    it "is invalid" do 
     subject.should_not be_valid 
    end 

    it "adds an error message for the #{attr_name}" do 
     subject.save.should be_false 
     subject.errors.messages[attr_name].first.should =~ /unknown isn't a valid #{attr_name}/ 
    end 
    end 
end 

Sonra bu gibi özelliklerde diyebilirsiniz:

describe "validation" do 
    describe "#role" do 
    behaves_like "attribute in collection", :role, User::ROLES 
    end 
end 

bu test mı ama işe gerektiğini düşünüyorum.

+0

Şaşırtıcı, teşekkürler. – kolrie

2

Sen shared_examples tekniği ile bu şekilde sizin spec KURU edebilirsiniz. İlk önce ve sonra sadece DRY'ing'in okunabilir olması gerektiğine inanıyorum. Eğer bazı özellikleri göz ardı ederseniz, muhtemelen bu kodu okuma/yeniden kurma/değiştirme için bir baş ağrısı olacaktır.

+0

Anlaşıldı. Ya yapmak için iyi bir yol arıyordum ya da birileri bana gerçekten ne yaptığını anlatıyordu. Küçük parçaları kopyalayıp yapıştırıp KURUTACAK. Teşekkür ederim. – kolrie

+0

Bu "shared_examples_for" ve "shared_examples" değil mi? –

+0

'shared_examples' çalışır – alex