Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 286
99miles Avatar asked Jun 10 '11 03:06

99miles


2 Answers

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...
like image 161
zetetic Avatar answered Nov 05 '22 02:11

zetetic


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.

like image 28
nathanvda Avatar answered Nov 05 '22 00:11

nathanvda