2012-12-22 24 views
5

Trong Rails của tôi 3 ứng dụng, tôi có một spec RSpec để kiểm tra hành vi của một lĩnh vực nhất định (vai trò trong tài mô hình) để đảm bảo rằng giá trị nằm trong một danh sách các giá trị hợp lệ.Dùng lại RSpec hành vi xác nhận

Bây giờ tôi sẽ có cùng một thông số kỹ thuật chính xác cho một trường khác, trong một mô hình khác với một tập hợp các giá trị hợp lệ khác. Tôi muốn trích xuất các mã phổ biến thay vì chỉ sao chép và dán nó, thay đổi các biến.

Tôi tự hỏi liệu đây có phải là trường hợp sử dụng ví dụ chia sẻ ví dụ hoặc kỹ thuật sử dụng lại RSpec khác không.

Dưới đây là đoạn code RSpec liên quan:

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 

gì sẽ là trường hợp tốt nhất để tái sử dụng mã này, nhưng giải nén vai trò (lĩnh vực này được xác minh) và tài khoản :: VAI TRÒ (thu giá trị hợp lệ) vào các tham số được chuyển tới mã này?

Trả lời

2

Tôi nghĩ đây là trường hợp sử dụng hoàn toàn hợp lý cho các ví dụ được chia sẻ. ví dụ. một cái gì đó như thế này:

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 

Sau đó, bạn có thể gọi nó trong thông số kỹ thuật của bạn như thế này:

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

đã không được thử nghiệm này nhưng tôi nghĩ rằng nó sẽ làm việc.

+0

Thật tuyệt vời, cảm ơn. – kolrie

2

Bạn có thể KHÔ spec của bạn với shared_examples technic theo cách này:

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 

Nhưng những gì về ý tưởng của bạn để khô vài specs..I nghĩ nó quá nhiều. Tôi thuyết phục rằng spec phải được đọc trước tiên và chỉ sau đó DRY'ing. Nếu bạn DRY vài thông số kỹ thuật, nó sẽ có thể là một nhức đầu cho tương lai đọc/refactoring/thay đổi mã này.

+0

Đồng ý. Tôi đang tìm kiếm một cách hay để làm điều đó hoặc một người nào đó thực sự nói với tôi những gì bạn vừa làm. Tôi sẽ sao chép và dán và DRY miếng nhỏ. Cảm ơn bạn. – kolrie

+0

Không nên là 'shared_examples_for' và không phải là' shared_examples'? –

+0

'shared_examples' sẽ hoạt động – alex

Các vấn đề liên quan