开发者

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)
    resp开发者_开发技巧ond_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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜