2011-06-10 115 views
7

给定一个像这样的控制器,它可以创建多个实例变量以供视图使用,您通常会测试每个变量是否设置正确?这看起来像你想要的,但它似乎也有点可能有点棘手。什么是正确的方法?使用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

回答

11

如果你打算编写一个控制器规范,那么是的,所有的意思都是测试实例变量的分配。大部分“trickiness”可以来自其他型号/库的依赖关系,因此,踩灭了那些方法调用:

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

希望这有助于。