【问题标题】:Cannot test with rspec controller POST create action( devise and cancan)无法使用 rspec 控制器 POST 创建操作进行测试(设计和 cancan)
【发布时间】:2023-09-09 13:36:02
【问题描述】:

我很难让控制器通过 rspec 测试。我想测试 POST 创建操作是否有效。我正在使用 rails (3.0.3)、cancan (1.4.1)、devise (1.1.5)、rspec (2.3.0)

模型非常简单

class Account < ActiveRecord::Base
  attr_accessible :name 
end

控制器也是标准的(直接从脚手架出来)

class AccountsController < ApplicationController
  before_filter :authenticate_user!, :except => [:show, :index]
  load_and_authorize_resource
  ...

  def create
    @account = Account.new(params[:account])

    respond_to do |format|
      if @account.save
        format.html { redirect_to(@account, :notice => 'Account was successfully created.') }
        format.xml  { render :xml => @account, :status => :created, :location => @account }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @account.errors, :status => :unprocessable_entity }
      end
    end
  end

我想通过的 rspec 测试是(请原谅标题,也许不是最合适的)

 it "should call create on account when POST create is called" do
   @user = Factory.create(:user)
   @user.admin = true
   @user.save

   sign_in @user #this is an admin
   post :create, :account => {"name" => "Jimmy Johnes"}
   response.should be_success
   sign_out @user

 end

然而我得到的只是

AccountsController get index should call create on account when POST create is called
 Failure/Error: response.should be_success
 expected success? to return true, got false
 # ./spec/controllers/accounts_controller_spec.rb:46

可以测试其他操作并通过(即 GET new)

这里是 GET new 的测试

it "should allow logged in admin to call new on account controller" do
  @user = Factory.create(:user)
  @user.admin=true
  @user.save

  sign_in @user #this is an admin
  get :new
  response.should be_success
  sign_out @user
end

这里是技能文件

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new
    if user.admin?
      can :manage, :all
    else
      can :read, :all
    end
  end
end

有什么想法吗?我的猜测是我使用了错误的 rspec 期望,因为代码确实有效(只是测试没有按预期执行!)

【问题讨论】:

    标签: ruby-on-rails rspec devise cancan


    【解决方案1】:

    response.should be_success 如果响应代码在 200-299 范围内,则返回 true。但是创建操作重定向,所以响应代码被设置为 302,因此失败。

    您可以使用response.should redirect_to 对此进行测试。查看标准 RSpec 控制器生成器的输出示例,可能如下所示:

      it "redirects to the created account" do
        Account.stub(:new) { mock_account(:save => true) }
        post :create, :account => {}
        response.should redirect_to(account_url(mock_account))
      end
    

    【讨论】:

    • zetetic,你的回答非常好。我必须花几个星期才能让它通过,但它的要点是它应该是一个重定向。
    • 我将其选为已接受的答案,因为大多数人似乎认为此答案最有用
    【解决方案2】:

    使测试通过的 rspec 测试是(感谢 zetetic 的建议):

        it "should call create on account when POST create is called" do
        @user = Factory.create(:user)
        @user.admin = true
        @user.save
    
        sign_in @user #this is an admin
        account = mock_model(Account, :attributes= => true, :save => true) 
        Account.stub(:new) { account }
    
        post :create, :account => {}
        response.should redirect_to(account_path(account))
        sign_out @user
    
    end
    

    【讨论】:

      最近更新 更多