简体   繁体   中英

Testing instance variables in controller with RSpec

Given a controller like this where it creates several instance variables for use by the view, would you generally test that each of those get set properly? It seems like you would want to, but it also seems a little it could be a bit tricky. What's the right approach?

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

The code is also posted at https://gist.github.com/1018190

If you're going to write a controller spec, then yes, by all means test that the instance variables are assigned. Much of the 'trickiness' can come from dependencies on other models/libraries, so stub out those method calls:

# 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...

I would split it up as follows: test that the index calls the correct method. Then test whether the method works.

So something like

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

Hope this helps.

So long as you have good coverage around your method, you can test that your method is being called at the right times, with the right values etc. Something like:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM