使用RSpec测试Rails控制器 - 如何测试:current_account.projects

时间:2012-03-26 18:37:00

标签: ruby-on-rails unit-testing rspec authlogic controllers

我正在使用Rspec和Rails 3进行测试。我已经测试了我的模型和助手,但我对如何开始测试控制器感到迷茫。我的控制器操作中的几乎所有数据都是使用类似这样的示例来提取的:

@services = current_account.services

@projects = current_person.projects

@projects = current_account.projects.active 
# this is really @projects = current_person.account.projects.active)

我似乎无法找到如何测试以这种方式拉动的数据的任何示例。我发现的所有示例都不是作用于帐户或个人。谁能指点我一篇关于如何模拟或存根此类安排的文章?这是否表示整个方法不正确?下面,我已经包含了一个完整的样本控制器。

非常感谢任何帮助。

谢谢, 大卫

class ServicesController < ApplicationController
  # Run authorizations
  filter_resource_access

  # Respond to ...
  respond_to :html, :xml, :json
  respond_to :js,   :only => [:new, :create, :edit, :update, :destroy]

  # GET /services
  # GET /services.xml
  def index
    @services = current_account.services.order("name").paginate(:page => params[:page])

    respond_with(@services)
  end

  # GET /services/1
  # GET /services/1.xml
  def show
    @service = current_account.services.find(params[:id])

    respond_with(@service)
  end

  # GET /services/new
  # GET /services/new.xml
  def new
    @service = current_account.services.new

    respond_with(@service)
  end

  # GET /services/1/edit
  def edit
    @service = current_account.services.find(params[:id])

    respond_with(@service)
  end

  # POST /services
  # POST /services.xml
  def create
    @service = current_account.services.new(params[:service])

    if @service.save
      # flash[:notice] = 'A service was successfully created.'
    end

    respond_with(@service, :location => services_url)
  end

  # PUT /services/1
  # PUT /services/1.xml
  def update
    @service = current_account.services.find(params[:id])

    if @service.update_attributes(params[:service])
      # flash[:notice] = 'The service was successfully updated.'
    end

    respond_with(@service, :location => services_url)
  end

  # DELETE /services/1
  # DELETE /services/1.xml
  def destroy
    @service = current_account.services.find(params[:id])

    if @service.destroy
      flash[:notice]  = "The service was successfully deleted."
    else
      flash[:warning] = @service.errors.full_messages.inject("") { |acc, message| acc += message  }
    end

    respond_with(@service)
  end
end

------更新

感谢Xaid的解决方案,我得到了一个解决方案:

  context "logged_in" do
    before(:each) do
      @current_account = Factory.create(:account)
      controller.stub!(:current_account).and_return(@current_account)

      @services = FactoryGirl.create_list(:service, 10, :account => @current_account)
      @services << @current_account.services.first
      @current_account.services.stub!(:all).and_return(@services)
    end


    # INDEX
    describe "GET services" do
      before(:each) do
        get :index
      end

      it "should set @services when accessing GET /index" do
        assigns[:services].should == @services
      end

      it "should respond with success" do
        response.should be_success
      end
    end
  end

1 个答案:

答案 0 :(得分:4)

你不能用这样的东西测试你的'索引'动作

describe "GET 'index'" do
  before(:each) do
    @user = FactoryGirl.create(:user)
    controller.stub!(:current_user).and_return(@user)
    @services = FactoryGirl.create_list(:service, 10, :user => @user)
    @user.services.stub!(:all).and_return(@services)
  end

  it "should return a list of services" do
    get :index
    assigns(:services).should == @services
  end
end

如果我正确理解了您的问题,您应该能够存储current_user.services(或项目)并使其返回一些已知值(在我的示例中由FactoryGirl生成)并根据您的操作中存储的值进行检查(例如,'index'动作中的@services。