如何编写带身份验证的 Rspec 控制器测试?
How to write an Rspec controller test with authentication?
我有两个模型:
# 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
我正在尝试使用 Rspec and factory_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
才能通过测试。我以为我必须显式调用身份验证方法,但事实可能并非如此。我正在尝试测试团队控制器...而不是用户身份验证。
如有任何建议,我们将不胜感激。
我会在你的 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
你的情况可能不需要设计映射行,但如果不检查你的完整应用程序就不能说。
我有两个模型:
# 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
我正在尝试使用 Rspec and factory_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
才能通过测试。我以为我必须显式调用身份验证方法,但事实可能并非如此。我正在尝试测试团队控制器...而不是用户身份验证。
如有任何建议,我们将不胜感激。
我会在你的 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
你的情况可能不需要设计映射行,但如果不检查你的完整应用程序就不能说。