【问题标题】:How to access (devise) current_user in a rspec feature test?如何在 rspec 功能测试中访问(设计)current_user?
【发布时间】:2014-07-10 17:02:33
【问题描述】:

在设计文档中,他们提供了有关在测试控制器时如何访问 current_user 的提示:

https://github.com/plataformatec/devise/wiki/How-To:-Test-controllers-with-Rails-3-and-4-%28and-RSpec%29

但是,在进行功能测试时呢?我正在尝试测试我的一个控制器的创建方法,并在该控制器中使用 current_user 变量。

问题在于 devise 中建议的宏使用了 @request 变量,而对于功能规范来说它是 nil。什么是解决方法?

编辑:

这就是我目前的规格:

feature 'As a user I manage the orders of the system' do
  scenario 'User is logged in ad an admin' do
    user = create(:user)
    order = create(:order, user: user)
    visit orders_path
    #Expectations
  end
end

问题是在我的OrdersController 中我有一个current_user.orders 调用,并且由于current_user 没有定义,它会将我重定向到/users/sign_in

我在/spec/features/manage_orders.rb下定义了这个

【问题讨论】:

标签: ruby-on-rails ruby rspec devise


【解决方案1】:

来自https://github.com/plataformatec/devise/wiki/How-To:-Test-controllers-with-Rails-3-and-4-%28and-RSpec%29

如果我对你的理解正确,也许你需要使用

subject.current_user.email
#or
controller.current_user.email

例如:

describe OrdersController, :type => :controller do
  login_user

  describe "POST 'create'" do
     it "with valid parametres" do
        post 'create', title: 'example order', email: subject.current_user.email
     end
  end
end

controller_macros.rb:

module ControllerMacros
  def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      user = FactoryGirl.create(:user)
      #user.confirm! # or set a confirmed_at inside the factory. Only necessary if you are using the "confirmable" module
      sign_in user
    end
  end
end

不要忘记将其包含在您的 spec_helper.rb 中:

config.include Devise::TestHelpers, type: :controller
config.extend ControllerMacros, type: :controller

【讨论】:

  • 这对我有用:subject.current_user.email
  • controller_macros.rb 放在哪里?在规范/支持文件夹中?
  • @aldrien.h 是的。
  • @Hommer Smith 这是正确的答案。我也对其进行了测试,并且可以正常工作。如果它被接受,它将在搜索查询中显示为已解决。
  • 这个答案以及该设计 wiki 页面适用于控制器规格。问题是关于功能规格;并且设计有一个单独的页面:github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara
【解决方案2】:

您可以将 login_user 定义为用户登录的方法,如下所示(放在 support 文件夹中):

def login_user
  Warden.test_mode!
  user = create(:user)
  login_as user, :scope => :user
  user.confirmed_at = Time.now
  user.confirm!
  user.save
  user
end

然后在场景中说:

user = login_user

【讨论】:

    【解决方案3】:

    这就是我认为您正在寻找的东西:

    require 'spec_helper'
    include Warden::Test::Helpers
    Warden.test_mode!
    
    feature 'As a user I manage the orders of the system' do
      scenario 'User is logged in ad an admin' do
        user = create(:user)
        login_as(user, scope: :user)
        order = create(:order, user: user)
        visit orders_path
        #Expectations
      end
    end
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多