2011-08-25 30 views
0

,有4類用戶:非登錄,消費者,生產者和管理員。Rspec,在我的系統中有更好的方式來編寫這個

我目前使用的是Cancan for ACL。

在寫RSpec的,我看到以下內容:

describe DealsController do 

    describe "non-signed-in users" do 
    before(:each) do 
     @deal = Factory(:deal) 
    end 

    describe "should be able to" do 
     it "access index" do get :index end 
     it "show deal" do get :show, :id => @deal end 

     after(:each) do 
     response.should be_success 
     end 
    end 

    describe "should not be able to" do 
     it "redeem" do get :redeem end 
     it "new" do get :new end 
     it "edit" do get :edit, :id => @deal end 
     it "update" do get :update, :id => @deal end 
     it "destroy" do get :destroy, :id => @deal end 

     after(:each) do 
     response.should_not be_success 
     response.should redirect_to(root_path) 
     flash[:error].should == "Permission denied." 
     end 
    end 
    end 

    describe "consumers" do 
    before(:each) do 
     @user = test_sign_in(Factory(:user, :role => "consumer")) 
     @deal = Factory(:deal) 
    end 

    describe "should be able to" do 
     it "access index" do get :index end 
     it "show deal" do get :show, :id => @deal end 

     after(:each) do 
     response.should be_success 
     end 
    end 

    describe "should not be able to" do 
     it "redeem" do get :redeem end 
     it "new" do get :new end 
     ... 


     after(:each) do 
     response.should_not be_success 
     response.should redirect_to(root_path) 
     flash[:error].should == "Permission denied." 
     end 
    end 
end 

    describe "producer" do 
    before(:each) do 
     @user = test_sign_in(Factory(:user, :role => "producer")) 
     @business = Factory(:business, :user_id => @user.id) 
     @deal = Factory(:deal, :business_id => @business.id) 
    end 

    it "should be able to access index" do 
     get :index 
     response.should be_success 
    end 

    describe "in show deals" do 
     it "should be able to see merchant controls for his deal" do 
     get :show, :id => @deal 
     response.should have_selector('h3', :content => "Merchant Controls") 
     end 

     it "should not be able to see merchant controls for other's deal" do 
     @user2 = Factory(:user, :role => "producer") 
     @business2 = Factory(:business, :user_id => @user2.id) 
     @deal2 = Factory(:deal, :business_id => @business2.id) 
     get :show, :id => @deal2 

     response.should_not have_selector('h3', :content => "Merchant Controls") 
     end 
    end 

    describe "should not be able to" do 
     it "new" do get :new end 
     ... 

     after(:each) do 
     response.should_not be_success 
     response.should redirect_to(root_path) 
     flash[:error].should == "Permission denied." 
     end 
    end 
end 

end 

我還沒有填寫管理部分,但我非常有信心,這是不推薦的方式去這樣做。

什麼是更好的方法?

回答

0

老實說,如果它是一個你關心的應用程序 - 特別是涉及用戶交互的時候 - 有很多驗收測試是不錯的。顯然,不要被帶走,並開始測試某些顏色是否可見等。但是如果你沒有完全測試,你就不會成爲你的程序員。

儘管您可能想要將測試分解爲更易於管理的測試。也許爲這四種用戶類型分別創建一個單獨的物理文件。我不記得了,但我不認爲這會導致RSpec出現任何問題。我個人認爲使用RSpec進行驗收測試太可怕了。太堅韌。我更喜歡使用黃瓜(http://www.cukes.info)。它使驗收測試更容易,尤其是如果你還想測試JavaScript。在我看來,他們寫得更快,更乾淨。如果我是你看看它是否適合你,我會仔細考慮一下。

4

你應該考慮採用一種新的單線風格。例如。做這樣的事情

describe "should be able to" do 
    it "access index" { get :index } 
    it "show deal" { get :show, :id => @deal } 
    after(:each)  { response.should be_success } 
end 

此外,你可能會考慮創建一個自定義的匹配器重複多行預期。例如,以下內容:

after(:each) do 
    response.should_not be_success 
    response.should redirect_to(root_path) 
    flash[:error].should == flash 
end 

可以用

after(:each) { response.should fail_redirect_and_flash(root_path, 'Permission denied.') } 

使用下面的自定義匹配代碼

RSpec::Matchers.define :fail_redirect_and_flash do |path,flash| 
    match do |response| 
    response.should_not be_success 
    response.should redirect_to(path) 
    flash[:error].should == flash 
    end 
end 

也將進行更換,很多人甚至不打擾寫控制器單元測試,因爲設計良好的控制器通常只有很少的代碼(他們通常只是使用模型上的方法設置一些變量並渲染/重定向,因此大多數測試實際上發生在我在模型中)。相反,他們將控制器和查看測試一起包裝並使用黃瓜。你仍然會得到一堆同樣難看的代碼,但有些人覺得管理起來更容易。

在這個筆記上,你會發現你的規格「不應該能夠看到商家控制其他人的交易」實際上是測試你的視圖,而不是你的控制器。您應該剔除您在控制器中使用的任何邏輯,以顯示商家控件並將其粘貼到幫助器中並單獨進行測試。這將有助於保持您的控制器精簡。例如。您可以在視圖中使用以下幫助程序

def merchant_controls(deal, business) 
    if business.can? :update, deal 
    # render html 
    end 
end 

而且您可以爲此輔助方法提供一個規範...

Describe "merchant_controls(deal, business)" do 
    before(:all) do 
    @business_a = create(:business) 
    @deal_a = create(:deal, :business_id => @business_a) 
    @business_b = create(:business) 
    @deal_b = create(:deal, :business_id => @business_b) 
    end 

    it "a business should see merchant controls next to its own deals" do 
    merchant_controls(@business_a, @deal_a).should eq("blahblah") 
    end 
    it "a business should not see merchant controls next to other business' deals" do 
    merchant_controls(@business_a, @deal_b).should eq("") 
    end 
end 

希望這會有所幫助。

+0

謝謝你的一切!我是rspec和測試新手,這真的很有幫助! – disappearedng

+0

FWIW,我明白,這可能只是發生在我身上,但我發現,對於一個工作與{...}和...工作... end結束,我必須在它之後用括號來解釋。即它(「應該做些什麼」){...}我使用Rspec 2.13,ruby 2,並且使用spork和guard與dRb進行測試。雖然很好的答案!希望我可以多次讚揚它! :) – engineerDave

相關問題