Ruby on rails 设计登录在控制器规范中不起作用

Ruby on rails 设计登录在控制器规范中不起作用,ruby-on-rails,devise,rspec-rails,ruby-on-rails-5.2,Ruby On Rails,Devise,Rspec Rails,Ruby On Rails 5.2,看来,这个设计的sign_-in-helper不起作用 常规登录程序就像一个魔咒,通过集成测试和手动填写登录表单进行测试。这两种方法都为当前用户提供了正确的值 我想测试用户配置文件的编辑控制器功能,但遇到了“未授权”问题。这让我想到了当前的规范,我只想批准实际上没有用户登录,因此,当前的用户为零 我想,我的代码中缺少了一些东西 你有什么办法解决我的问题吗 我正在使用Rails 5.2和ruby 2.5.0 models/user.rb class User < ApplicationRec

看来,这个设计的sign_-in-helper不起作用

常规登录程序就像一个魔咒,通过集成测试和手动填写登录表单进行测试。这两种方法都为当前用户提供了正确的值

我想测试用户配置文件的编辑控制器功能,但遇到了“未授权”问题。这让我想到了当前的规范,我只想批准实际上没有用户登录,因此,当前的用户为零

我想,我的代码中缺少了一些东西

你有什么办法解决我的问题吗

我正在使用Rails 5.2和ruby 2.5.0

models/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
规范/轨道\u 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
支持/控制器\u 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
最后,我的控制器规格:

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

根据您共享的内容,唯一跳出来的是,当我使用Desive in controller specs中的
sign_in
帮助程序时,我将其包装在
之前的
块(或花括号)中,类似于下面的内容,类似于您在
模块中的
登录_中的内容。也许可以试着摆脱
(:each)
。此外,您可以在
login\u user
方法中插入pry或byebug,以查看在运行控制器规格时该方法是否被击中

let!(:user) { create(:user) }

context 'user is logged in' do
  before { sign_in user }

  it 'allows some thing' do
    # some expectation....
  end
end

根据您共享的内容,唯一跳出来的是,当我使用Desive in controller specs中的
sign_in
帮助程序时,我将其包装在
之前的
块(或花括号)中,类似于下面的内容,类似于您在
模块中的
登录_中的内容。也许可以试着摆脱
(:each)
。此外,您可以在
login\u user
方法中插入pry或byebug,以查看在运行控制器规格时该方法是否被击中

let!(:user) { create(:user) }

context 'user is logged in' do
  before { sign_in user }

  it 'allows some thing' do
    # some expectation....
  end
end

在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
也可以),但我对此很满意


也许没有人想解释,为什么它必须是Specs/support/controller\u 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\u in user

使用byebug显示登录用户方法被命中。我在尝试使用User.first获取用户时批准了该操作。然而,使用byebug是一个很好的建议。在用户创建之后和调用sign_-in方法之前,我调用了byebug。在byebug控制台尝试登录用户不会产生任何结果,但调用subject.sign\u-in-user会起作用。使用byebug表明登录用户方法被命中。我在尝试使用User.first获取用户时批准了该操作。然而,使用byebug是一个很好的建议。在用户创建之后和调用sign_-in方法之前,我调用了byebug。在byebug控制台尝试登录用户不会产生任何结果,但是调用subject.sign\u-in-user就可以了。最后我找到了这个解决方案!谢谢!我终于找到了这个解决方案!谢谢!
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