【问题标题】:How to write an Rspec controller test with authentication?如何编写带有身份验证的 Rspec 控制器测试?
【发布时间】:2015-09-16 14:44:10
【问题描述】:

我有两个模型:

# app/models/user.rb
class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :confirmable

  has_many :teams, dependent: :destroy
end

# app/models/team.rb
class Team < ActiveRecord::Base
  belongs_to :user

  validates_presence_of :user
end

我正在尝试使用Rspecfactory_girl_rails 测试我的TeamsController

在创建新团队之前,我需要一个经过身份验证的用户。

我创建了一个:用户工厂:

FactoryGirl.define do
  factory :user do
    first_name   "John"
    last_name    "Doe"
    email        {|n| "email#{n}@email.com" }
    mobile_phone "1235551234"
    company_name "Widgets Inc."
    password     "password"
  end
end

这里是teams_controller_spec.rb的相关部分:

require 'rails_helper'

RSpec.describe TeamsController, type: :controller do

  # This should return the minimal set of values that should be in the session
  # in order to pass any filters (e.g. authentication) defined in
  # TeamsController. Be sure to keep this updated too.
  let(:valid_session) { {} }

  describe "GET #index" do
    it "assigns all teams as @teams" do
      user = FactoryGirl.create(:user)

      team = Team.create!(name: "New Team Name", user: user)

      get :index, {}, valid_session
      expect(assigns(:teams)).to eq([team])
    end
  end
end

测试失败:

1) TeamsController GET #index assigns all teams as @teams
     Failure/Error: get :index, {}, valid_session
     NoMethodError:
       undefined method `authenticate' for nil:NilClass

我不明白我需要如何填充 :valid_session 才能通过测试。我以为我必须显式调用身份验证方法,但这可能不是真的。我正在尝试测试团队控制器...不是用户身份验证。

任何建议将不胜感激。

【问题讨论】:

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


【解决方案1】:

我会在你的 rails_helper 中这样做:

module ControllerMacros    
  def sign_me_in
    before :each do
      @request.env['devise.mapping'] = Devise.mappings[:user]
      @current_user = FactoryGirl.create(:user)
      sign_in :user, @current_user
    end 
  end 
end

Rspec.configure do |config|
    #other rspec stuff
    config.include FactoryGirl::Syntax::Methods
    config.extend ControllerMacros, type: :controller
    config.include Devise::Test::ControllerHelpers, type: :controller
 end

然后在您的控制器规范中,(前提是您需要 rails_helper)您可以在任何时候登录 sign_me_in 而不必担心 valid_session:

RSpec.describe TeamsController, type: :controller do
  sign_me_in
  #etc...
end

但是,在您的具体情况下,您想知道您的登录身份,因此您可以这样做:

RSpec.describe TeamsController, type: :controller do
  describe "GET #index" do
    it "assigns all teams as @teams" do
      user = FactoryGirl.create(:user)
      team = Team.create!(name: "New Team Name", user: user)
      @request.env['devise.mapping'] = Devise.mappings[:user]
      sign_in :user, user
      get :index
      expect(assigns(:teams)).to eq([team])
    end
  end
end

在您的情况下可能不需要设计映射行,但如果不检查您的完整应用程序就不能说。

【讨论】:

  • 这很棒@Yule - 谢谢!当我按照您编写的方式运行 GET #Index 测试时,我看到了这个失败:goo.gl/6307Ke sign_in 来自哪里?
  • 抱歉,错过了 RSpec 配置。编辑后的答案:config.include Devise::TestHelpers, type: :controller 在您的 rails_helper 中
  • Devise::TestHelpers 已弃用。请改用Devise::Test::ControllerHelpers
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多