2016-10-20 52 views
0

考慮以下代碼片段:如何重構這個rails規範?

context 'votes' do 
    it { should_not be_able_to :vote_yes, create(:question, user: user), user: user } 
    it { should be_able_to :vote_yes, create(:question, user: other_user), user: user } 
    it { should_not be_able_to :vote_no, create(:question, user: user), user: user } 
    it { should be_able_to :vote_no, create(:question, user: other_user), user: user } 
    it { should_not be_able_to :reject_vote, create(:question, user: user), user: user } 
    it { should be_able_to :reject_vote, create(:question, user: other_user), user: user } 

    it { should_not be_able_to :vote_yes, create(:answer, user: user), user: user } 
    it { should be_able_to :vote_yes, create(:answer, user: other_user), user: user } 
    it { should_not be_able_to :vote_no, create(:answer, user: user), user: user } 
    it { should be_able_to :vote_no, create(:answer, user: other_user), user: user } 
    it { should_not be_able_to :reject_vote, create(:answer, user: user), user: user } 
    it { should be_able_to :reject_vote, create(:answer, user: other_user), user: user } 
end 

如何重構到的東西用更少的線條和重複?

回答

2

我會做的第一件事情就是你的測試分成多個邏輯分組,因爲它是目前非常混亂(一覽)預期的行爲是什麼:

context 'voting yes' do 
    it { should be_able_to :vote_yes, create(:answer, user: other_user), user: user } 
    it { should_not be_able_to :vote_yes, create(:question, user: user), user: user } 

    it { should be_able_to :vote_yes, create(:question, user: other_user), user: user } 
    it { should_not be_able_to :vote_yes, create(:answer, user: user), user: user } 
end 

context 'voting no' do 
    it { should be_able_to :vote_no, create(:question, user: other_user), user: user } 
    it { should_not be_able_to :vote_no, create(:question, user: user), user: user } 

    it { should be_able_to :vote_no, create(:answer, user: other_user), user: user } 
    it { should_not be_able_to :vote_no, create(:answer, user: user), user: user } 
end 

context 'rejecting vote' do 
    it { should be_able_to :reject_vote, create(:question, user: other_user), user: user } 
    it { should_not be_able_to :reject_vote, create(:question, user: user), user: user } 

    it { should be_able_to :reject_vote, create(:answer, user: other_user), user: user } 
    it { should_not be_able_to :reject_vote, create(:answer, user: user), user: user } 
end 

在這個重組的測試列表展望,看到明確的行爲模式要容易得多。你可以刪除重複如下:

%i(vote_yes vote_no reject_vote).each do |action_performed| 
    context "can #{action_performed} against other users" do 
    it { should be_able_to action_performed, create(:question, user: other_user), user: user } 
    it { should be_able_to action_performed, create(:answer, user: other_user), user: user } 
    end 

    context "cannot #{action_performed} against self" do 
    it { should_not be_able_to action_performed, create(:question, user: user), user: user } 
    it { should_not be_able_to action_performed, create(:answer, user: user), user: user } 
    end 
end 

你甚至可能會傾向於進一步採取這一步questionanswer測試之間消除重複:

%i(vote_yes vote_no reject_vote).each do |action_performed| 
    %i(question answer).each do |record_type| 
    it "can #{action_performed} against #{record_type} for other users" do 
     should be_able_to action_performed, create(record_type, user: other_user), user: user 
    end 

    it "cannot #{action_performed} against #{record_type} for self" do 
     should_not be_able_to action_performed, create(record_type, user: user), user: user 
    end 
    end 
end 

然而,這可能使測試更難理解和編輯,所以我會建議反對它......也許如果該記錄類型列表(question,answer,...)增長更長,那麼你可以考慮這樣的方法。

+0

另外爲了將來的參考,這樣的問題更適合[代碼評論](http://codereview.stackexchange.com/)StackExchange網站。 –