Devise sign_in在控制器规范中不起作用

时间:2018-05-31 17:30:03

标签: ruby-on-rails devise rspec-rails ruby-on-rails-5.2

看来,设计的sign_in帮手并不起作用。

常规登录过程作为魅力,通过集成测试和手动填写登录表单进行测试。两种方法都为current_user提供了正确的值。

我想测试用户个人资料的编辑控制器功能,然后遇到“未经授权的”#39;问题。这导致了我目前的规格,我只是想批准实际上没有用户登录,因此,current_user是零。

我想,我的代码中只有一些missig。

你有什么提示可以解决我的问题吗?

我使用 Rails 5.2 ruby​​ 2.5.0

模型/ user.rb

class User < ApplicationRecord
  enum role: [:registered, :editor, :admin]
  after_initialize :set_default_role, if: :new_record?

  def set_default_role
    self.role ||= :registered
  end

  # Include default devise modules. Others available are:
  devise :invitable, :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

控制器/ application_controller.rb

class ApplicationController < ActionController::Base

  before_action :authenticate_user!
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name,  :last_name, :approved])
  end
end

控制器/ registration_controller.rb

class RegistrationsController < Devise::RegistrationsController

  private

  def after_inactive_sign_up_path_for(resource)
    show_post_register_info_path
  end   
end

配置/ route.rb

Rails.application.routes.draw do

  devise_for :users, controllers: { registrations: 'registrations'}

  root to: 'welcome#home
  get 'show_post_register_info', to: 'static_pages#show_post_register_info'
end

规格/ rails_heper.rb

require 'rspec/rails'
require 'devise'

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

RSpec.configure do |config|
  config.include Devise::Test::ControllerHelpers, type: :controller
  config.include Devise::Test::ControllerHelpers, type: :view
  config.include Devise::Test::IntegrationHelpers
  config.extend ControllerMacros, type: :controller
  ...
end

支持/ controller_macros.rb

module ControllerMacros
  def login_user
    before(:each) do
        @request.env["devise.mapping"] = Devise.mappings[:user]
        user = FactoryBot.create(:user)
        sign_in user
    end
  end
end

最后,我的controller_spec:

require 'rails_helper'

RSpec.describe RegistrationsController, type: :controller do

describe 'registrations#update'  do

    context 'signing in a registered user' do
      login_user

      it 'should have a current_user' do
        expect(subject.current_user).to_not eq(nil)
      end

      it 'should be signed in' do
        expect(subject.user_signed_in?).to be true
      end
    end
  end
end

结果:

1) RegistrationsController registrations#update as a registered user changes the password
 Failure/Error: expect(subject.user_signed_in?).to be true

   expected true
        got false

2) RegistrationsController registrations#update as a registered user should have a current_user
 Failure/Error: expect(subject.current_user).to_not eq(nil)

   expected: value != nil
        got: nil

2 个答案:

答案 0 :(得分:2)

根据您分享的内容,唯一跳出来的是,当我在控制器规范中使用Devise的sign_in帮助器时,我将其包含在{{1}中阻止(或大括号),类似于下面的内容,类似于before模块中的内容。也许试着摆脱login_in。此外,您可以在(:each)方法中粘贴pry或byebug,以查看在运行控制器规范时该方法是否被命中。

login_user

答案 1 :(得分:0)

在Specs / support / controller_macros.rb中,我稍微编辑了登录程序:

def login_user
  before  do
    @request.env["devise.mapping"] = Devise.mappings[:user]
    user = FactoryBot.create(:user)
    subject.sign_in user # was sign_in user
  end
end

我真的不知道为什么我必须从控制器对象调用sign_in方法(controller.sign_in也可以),但我对此感到满意。

也许有人想解释,为什么它必须是subject.sign_in user