簡體   English   中英

使用RSpec和存根的故障測試控制器

[英]Trouble testing controller using rspec and stubs

我很難通過before_filters,異常以及一些模擬和存根來測試我的控制器。 這是控制器:

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)>'

感謝幫助!

我沒有看到問題,但這是一個重構建議。 如果您發現自己通常使用更多的模擬和存根,也許是時候重新考慮您的界面了​​。 在這種情況下,可以使控制器更纖細,模型更胖。

# 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

如果您刪除了@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 [:error]? before過濾器是處理這種情況的正確位置,因此它不應引發必須在其他地方進行挽救的異常(否則,它將向用戶顯示500頁)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM