rspec + Devise:current_user在测试中为零

时间:2015-11-28 04:58:40

标签: ruby-on-rails ruby rspec devise

我正在使用Devise为我的用户登录和东西以及rspec进行测试。我查看了rspec的Devise测试指南,并将ControllerMicros混合到控制器规格中。 事实上,如果我有这样的测试组织,事情一切正常:

  describe 'GET #index' do
    context 'user logged in but not admin' do
      login_user
      it 'should redirect to root_path for non_user' do
        get :index
        // I have asserted that the current_user here is not nil
        expect(response).to redirect_to(root_path)
      end
    end
  end

但是,如果我在上下文中有2个测试,并且我的非首次测试的current_user为nil。

  describe 'GET #index' do
    context 'user logged in but not admin' do
      login_user
      it 'should redirect to root_path for non_user' do
        get :index
        // I have asserted that the current_user here is not nil
        expect(response).to redirect_to(root_path)
      end

      it 'should do some other thing' do
        get :index
        // the current_user method returns nil here
        expect(response).to redirect_to(root_path)
      end
    end
  end

最糟糕的是,似乎这个问题不是确定性的:有些随机发生 - 导致几次失败后,套件刚刚在我的计算机上传递(但仍然在Travis my build上失败)

其他一些信息:

ControllerMacro.rb

module ControllerMacros
  def login_admin
    before(:each) do
      # @request.env["devise.mapping"] = Devise.mappings[:user]
      user = User.find_by(email: 'default_admin@controller.spec')
      user ||= FactoryGirl.create(:user, email: 'default_admin@controller.spec', uid: 'default_admin.controller.spec')
      admin = Admin.find_by(user_id: user.id)
      FactoryGirl.create(:admin, user: user) if not admin
      sign_in user
    end
  end

  def login_user(user = nil)
    before(:each) do
      # @request.env["devise.mapping"] = Devise.mappings[:user]
      user ||= User.find_by(email: 'default_user@controller.spec')
      user ||= FactoryGirl.create(:user, email: 'default_user@controller.spec', uid: 'default_user.controller.spec')
      sign_in user
    end
  end
end

rails_helper.rb

RSpec.configure do |config|
  # for loading devise in test
  config.include Devise::TestHelpers, :type => :controller
  config.extend ControllerMacros, :type => :controller
end

1 个答案:

答案 0 :(得分:1)

当你加载测试套件时运行false方法,你应该把它放在before:每个块中,为每次测试运行一次。

login_user

PS:不知道你在login_user方法中做了什么,但是Devise有一些很好的帮助,你可以包括如下

describe "GET index" do 
  before do
    login_user
  end
  it 'blabla' do
    get :index
    expect(response).to redirect_to(root_path)
  end
end

评论更新

如果您有多种类型的用户/设计登录条目,可以尝试指定您尝试登录用户的设计映射,如下所示:

#rails_helper.rb
RSpec.configure do |config|
  config.include Devise::TestHelpers, type: :controller
end

#then in you test 
before do
  sign_in user_instance
end