2011-06-17 75 views
1

我很難用before_filters,異常和一些模擬和存根測試我的控制器。 這裏是控制器:使用rspec和存根的故障測試控制器

before_filter :get_subject, :only => [:show, :edit, :update, :destroy, :update_field] 
before_filter :user_has_to_belongs_to_subject_company, :only => [:show, :edit, :update, :destroy, :update_field] 

def show 
    @messages = @subject.get_user_messages(current_user) 
end 

private 

def get_subject 
    @subject = Subject.find(params[:id]) 
end 

def user_has_to_belongs_to_subject_company 
    unless @current_user.company.eql?(@subject.company) 
    raise "Error: current_user does not belongs to subject's company" 
    end 
end 

這裏是我的規格文件:

require 'spec_helper' 

describe SubjectsController do 
    describe "for signed users" do 
    before(:each) do 
     @current_user = Factory(:user) 
     sign_in @current_user 
    end 

    describe "for user belonging to subject's company" do 
     before(:each) do 
     @subject = mock_model(Subject) 
     Subject.stub!(:find).with(@subject).and_return(@subject) 
     @current_user.stub_chain(:company, :eql?).and_return(true) 
     @subject.stub!(:company) 
     end 

     it "should not raise an exception" do 
     expect { get :show, :id => @subject }.to_not raise_error 
     end 
    end 

    describe "for user not belonging to subject's company" do 
     before(:each) do 
     @subject = mock_model(Subject) 
     Subject.stub!(:find).with(@subject).and_return(@subject) 
     @current_user.stub_chain(:company, :eql?).and_return(false) 
     @subject.stub!(:company) 
     end 

     it "should raise an exception" do 
     expect { get :show, :id => @subject }.to raise_error 
     end 
    end 
    end 
end 

最後,這裏是錯誤消息:

SubjectsController for signed users for user belonging to subject's company should not raise an exception 
    Failure/Error: expect { get :show, :id => @subject }.to_not raise_error 
    expected no Exception, got #<RuntimeError: Error: current_user does not belongs to subject's company> 
    # ./spec/controllers/subjects_controller_spec.rb:19:in `block (4 levels) in <top (required)>' 

THX的幫助!

+0

刪除我的答案,因爲我在閱讀時錯過了一些代碼。 – jaydel 2011-06-17 12:41:18

回答

1

我沒有看到問題,但這裏有一個重構建議。如果你發現自己使用了更多的模擬和存根,那麼也許是時候重新考慮你的接口了。在這種情況下,你可以讓你的控制器變得更瘦,而且你的模型更加健壯。

# subjects_controller_spec.rb 
describe "for user belonging to subject's company" do 
    before(:each) do 
    @subject = mock_model(Subject, :verify_user => true) 
    Subject.stub!(:find).with(@subject).and_return(@subject) 
    end 

# subjects_controller.b 
def user_has_to_belongs_to_subject_company 
    @subject.verify_user(@current_user) 
end 

# subject.rb 
class Subject 
    def verify_user(user) 
    unless user.company.eql?(company) 
     raise "Error: current_user does not belongs to subject's company" 
    end 
+0

Thx它有很大的幫助。 – 2011-06-17 14:20:44

0

,如果你刪除在@current_user前面的@

def user_has_to_belongs_to_subject_company 
    unless @current_user.company.eql?(@subject.company) 

得到

def user_has_to_belongs_to_subject_company 
    unless current_user.company.eql?(@subject.company) 

而在你的規格,也controller.stub會發生什麼!(:CURRENT_USER).and_return @ current_user

我認爲問題是範圍之一 - 您的測試中的@current_user與控制器中的@current_user不同。真的取決於如何實現「sign_in @current_user」。

此外,而不是引發異常,也許你的before_filter可以重定向用戶到另一個頁面並設置flash [:錯誤]?之前的過濾器是處理這種情況的正確的地方,所以它不應該引發必須在其他地方拯救的異常(或者如果沒有,它會向用戶顯示500頁)。

+0

Thx太,我遵循你的建議,只是做了閃光[:錯誤]和重定向:) – 2011-06-17 14:21:09