使用RSpec在控制器中测试实例变量

时间:2011-06-10 03:53:25

标签: ruby-on-rails rspec

给定一个这样的控制器,它创建了几个供视图使用的实例变量,你通常会测试每个变量是否正确设置?看起来你会想要,但它似乎有点可能有点棘手。什么是正确的方法?

class StaffsController < ApplicationController

  def index
   set_index_vars
    @all_staff = Staff.find_staff_for_business_all_inclusive(current_business_id)
    respond_to do |format|
     format.html { render :action => "index", :locals => { :all_staff => @all_staff, :all_services => @all_services, :new_vacation => @new_vacation } }
    end
  end

  def set_index_vars
    @days_of_week = days_of_week
    @first_day_of_week = DefaultsConfig.first_day_of_week

    @all_services = Service.services_for_business(current_business_id)

    @new_vacation = StaffVacation.new
   @has_hit_staff_limit = current_user_plan.has_hit_staff_limit?
  end

end

该代码也发布在https://gist.github.com/1018190

3 个答案:

答案 0 :(得分:11)

如果你要写一个控制器规范,那么是的,一定要测试实例变量的分配。大多数'棘手'可能来自对其他模型/库的依赖,因此将这些方法调用存根:

# air code
Staff.stub(:find_staff_for_business_all_inclusive) {array_of_staff}
controller.stub(:days_of_week) {['Monday','Tuesday',....etc...]}
DefaultsConfig.stub(:first_day_of_week) {"Monday"}
Service.stub(:services_for_business).with(some_value_for_the_current_business_id).\
  and_return(some_relevant_value)
StaffVacation.stub(:new) {something_meaningful}
controller.stub_chain(:current_user_plan,:has_hit_staff_limit?) {false}

get :index
assigns(:days_of_week).should == ['Monday','Tuesday',....etc...]
# ...etc...

答案 1 :(得分:1)

我会将其拆分如下:测试index调用正确的方法。然后测试该方法是否有效。

类似

describe StaffsController do
  describe "GET #index" do
    it "calls set_index_vars" do
      controller.should_receive(:set_index_vars)
      get :index
    end
    # and your usual tests ...
  end

  describe "#set_index_vars" do
    before(:each) do
      # stub out the code not from this controller
      controller.stub_chain(:current_user_plan, :has_hit_staff_limit?).and_return(false)
      .. etc ..

      controller.set_index_vars
    end
    it { assigns(:days_of_week).should == controller.days_of_week }
    it { assigns(:has_hit_staff_limit).should be_false
    # etc ..
  end
end

希望这有帮助。

答案 2 :(得分:0)

只要您对方法有良好的覆盖率,就可以测试您的方法是在正确的时间调用,使用正确的值等等。例如:

describe StaffsController do
  describe "GET #index" do
    it "should call set_index_vars" do
      controller.should_receive(:set_index_vars)
      get :index
    end
  end

  describe "#set_index_vars" do
    it "should assign instance variables with correct values" do 
      # or wtv this is supposed to do
      get :index
      assigns(:days_of_week).should == controller.days_of_week 
      # etc ..
    end
  end
end