2011-08-25 2 views
0

을 쓰는 더 좋은 방법이 있어야합니다. 로그인하지 않은 사용자, Consumer, Producer 및 Admin의 4 가지 사용자 클래스가 있습니다.Rspec, 내 시스템에

현재 Cancan for ACL을 사용하고 있습니다. 심지어 관리자 섹션에서 작성되지 않은하지만이이 일에 대해 갈 수있는 권장 방법이 아니다 꽤 확신

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 

: RSpec에를 쓰는 동안

, 나는 다음과 같은보고하고있다.

더 좋은 방법이 있습니까?

답변

0

정직하게 말하자면, 특히 사용자 상호 작용이 관련된 응용 프로그램에 관심이 있다면 - 수락 테스트를 거치면 괜찮습니다. 분명히 말하려하지 마십시오. 특정 색상과 같은 것들을 테스트 해 볼 수 있습니다. 그러나 철저하게 테스트하지 않으면 프로그래머가 될 수 없습니다.

테스트를보다 관리하기 쉬운 테스트로 나눌 수 있습니다. 어쩌면 4 가지 사용자 유형 각각에 대해 별도의 실제 파일을 만들 수 있습니다. 기억이 나지 않지만, 이것이 RSpec에 어떤 종류의 문제도 일으키지 않는다고 생각합니다.

개인적으로 수용 테스트에 RSpec을 사용하는 것은 너무 끔찍하다고 생각합니다. 너무 껄끄 러운. 나는 오이 (http://www.cukes.info)를 사용하는 것을 선호한다. 특히 자바 스크립트를 테스트하고 싶다면 수용 테스트가 훨씬 쉬워집니다. 내 의견으로는 더 빨리 작성하고 정리할 수 있습니다. 나는 그것이 당신에게 옳은지 지켜보기 위해 조금만 들여다 보았습니다.

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 

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 

또한 다음과 같은 사용자 정의 정규 코드를 사용하여

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

로 대체 할 수있는, 많은 사람들은 컨트롤러 유닛 테스트 때문에를 작성 귀찮게하지 않습니다 잘 설계된 컨트롤러는 일반적으로 거의 코드가 없습니다 (대개 모델의 메서드를 사용하여 일부 변수를 설정하고 렌더링/리디렉션하므로 대부분의 테스트가 실제로 발생합니다. n 모델). 대신 컨트롤러와 뷰 테스트를 함께 랩하고 오이를 사용합니다. 여전히 코드가 엉망인 것처럼 보이지만 일부 사람들은 관리하기가 쉽습니다.

그 메모에서 "사양이 다른 거래에 대한 판매자 컨트롤을 볼 수 없어야합니다."라는 사실은 컨트롤러가 아닌보기를 실제로 테스트한다는 것을 알 수 있습니다. 판매자 컨트롤을 표시하고 도우미를 도우미에 배치하고 별도로 테스트하기 위해 컨트롤러에서 사용하는 논리를 모두 추출해야합니다. 이렇게하면 컨트롤러를 얇게 유지하는 데 도움이됩니다. 예 : 당신은 당신이 당신의 의견

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와 나는 이것이 나에게 일어날지도 모른다는 것을 이해한다. 그러나 나는 한 라이너가 {...} 대 V ... 할 일을하는 것을 발견한다. 나는 그 후에 괄호로 설명해야만한다. 즉, Rspec 2.13, ruby ​​2에 있으며 테스트를 위해 dRb와 함께 spork 및 guard를 사용하고 있습니다. 좋은 대답! 내가 한번 이상 upvote 수 있기를 빌어! :) – engineerDave