使用Devise身份验证的RSpec控制器测试

18

我在使用rspec测试控制器时,遇到了设备身份验证的问题。

我的设置如下:

我已经包含了

config.include Devise::TestHelpers, :type => :controller

在我的spec_helper.rb文件中

在我的merchants_controller_spec.rb文件中

describe MerchantsController do
  before :each do
    @user = Factory(:user)
    @merchant = Factory(:merchant, :user_id => @user.id,:is_approved => false, :is_blacklisted => false)
    controller.stub!(:current_user).and_return(@user)
  end
  describe "GET index" do
    it "assigns all merchants as @merchants" do
      merchant = Factory(:merchant,:is_approved => true, :is_blacklisted => false)
      get :index
      assigns(:merchants).should eq([merchant])
    end
  end
end

我的 merchants_controller.rb 文件

class MerchantsController < ApplicationController

  before_filter :authenticate_user!
  def index
    @merchants = Merchant.approved
    debugger
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @merchants }
    end
  end
end

我在 merchant model 中有一个已批准的范围。

scope :approved, where(:is_approved => true, :is_blacklisted => false)
现在我的问题是,尽管我存根了current_user并将@user作为current_user返回,但我的merchants_controller索引规范仍然失败。 但如果我注释掉authenticate_user!则规范通过,没有authenticate_user!会捕获index操作的调试器,但authenticate_user!不会捕获调试器。 我认为在subbing current_user中存在问题,但我无法弄清楚。 帮我解决这个问题..
2个回答

24

你是否已经阅读了关于 Github 上的文档:

Devise包括一些用于功能测试的测试帮助程序。要使用它们,只需在测试类中包含Devise :: TestHelpers,并使用sign_insign_out方法。这些方法与控制器中的签名相同:

sign_in :user, @user   # sign_in(scope, resource)
sign_in @user          # sign_in(resource)

sign_out :user         # sign_out(scope)
sign_out @user         # sign_out(resource)

1
我用sign_in @user替换了controller.stub!(:current_user).and_return(@user),但仍然没有解决我的问题。我认为用户仍未被验证,因为在index操作中调试器仍未被捕获。有什么想法吗? - Gagan
我希望我能给这个点赞两次。我有一个嵌套的工厂来创建我的管理员,但我无法弄清楚为什么用户被创建了但没有登录。 - Arel

9
另一种选择
RSpec.describe YourController, :type => :controller do
  before do
    user = FactoryGirl.create(:user)
    allow(controller).to receive(:authenticate_user!).and_return(true)
    allow(controller).to receive(:current_user).and_return(user)
  end

  # rest of the code
end

这对我来说是有效的,适用于我所有的测试。https://github.com/plataformatec/devise/wiki/How-To:-Stub-authentication-in-controller-specs和https://github.com/plataformatec/devise/wiki/How-To:-Test-controllers-with-Rails-3-and-4-%28and-RSpec%29上的指南适用于一个示例,但不适用于整个套件。 - Foton
我没有使用authenticate_user!的存根,而是使用了上面的答案(sign_in @user方法),以及你的第二个存根allow(controller).to receive(:current_user).and_return(user)。 - Randall Coding

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接