无法在验收测试中使用 sign_in 方法 Rspec
unable to use sign_in method in acceptance test Rspec
我最近在我的 rails 项目中添加了 Devise 和 CanCanCan 用于身份验证和许可。
结果它破坏了我之前做的大部分验收测试,例如:
resource 'Projects' do
route '/projects?{}', 'Projects collection' do
get 'Return all projects' do
example_request 'list all projects' do
expect(status).to eq 200
我知道为什么这段代码被破坏了:我没有@current_user,CanCan 拒绝了 CanCan::AccessDenied
.
的请求
我目前正在尝试对管理员用户进行身份验证,以便我的验收测试能够通过,正如我为管理员定义的 can :manage, :all
。
我偶然发现了很多像我这样的帖子,但没有解决方案有效,因为我找到的所有答案都是为控制器测试而设计的,而且 sign_in 方法显然对他们有用。
到目前为止我尝试了什么:
before(:each) do
sign_in admin
end
NoMethodError:
undefined method `sign_in' for #<RSpec::ExampleGroups::Projects::ProjectsProjectsCollection::GETReturnAllProjects:0x0000000005dc9948>
所以我尝试添加
RSpec.configure do |config|
config.include Devise::TestHelpers
Failure/Error: @request.env['action_controller.instance'] = @controller
NoMethodError:
undefined method `env' for nil:NilClass
据我所知,我不能这样做,因为我不是在控制器范围内进行测试,而是在测试资源,所以我没有@request,也没有@controller。
我做错了什么,如果没有,既然我包含了身份验证和权限,我该如何通过测试?
使用的版本:
cancancan (2.2.0)
devise (4.3.0)
rails (5.1.4)
ruby 2.5.0p0
rspec (3.7.0)
问题与描述的完全一样,我在验收测试中使用Devise helpers没有成功。
我的解决方法是从验收测试适应请求测试。
#spec/requests/projects_spec.rb
require 'rails_helper'
RSpec.describe Project, type: :request do
let!(:admin) { create(:user, is_admin: true) }
let!(:user) { create(:user) }
context 'admin logged in' do
before do
log_in admin
end
it 'Return all projects' do
get projects_path
expect(status).to eq 200
// more tests
end
// more tests
end
context 'Normal user logged in' do
before do
log_in user
end
// more tests
end
log_in
方法来自我自己创建的助手
# spec/support/session_helpers.rb
module SessionHelpers
def log_in(user, valid = true, strategy = :auth0)
valid ? mock_valid_auth_hash(user) : mock_invalid_auth_hash
Rails.application.env_config['omniauth.auth'] = OmniAuth.config.mock_auth[strategy.to_sym]
get user_google_oauth2_omniauth_callback_path
end
end
它只是在 请求级别 存根身份验证(注意 get user_google_oauth2_omniauth_callback_path
这是我的应用程序的身份验证回调)
我的回调是这样配置的:
#app/config/routes.rb
Rails.application.routes.draw do
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
devise_scope :user do
get 'sign_in', to: 'devise/sessions#new', as: :new_user_session
delete 'sign_out', to: 'devise/sessions#destroy', as: :destroy_user_session
end
# app/controllers/users/omniauth_callbacks_controller.rb
module Users
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
include Devise::Controllers::Rememberable
def google_oauth2
@user = User.from_omniauth(request.env['omniauth.auth'])
if @user
sign_in_and_redirect @user
else
redirect_to root_path, notice: 'User not registered'
end
end
// more code
end
end
与其他助手一起(我的提供者是 Omniauth)
#spec/support/omniauth_macros.rb
module OmniauthMacros
def mock_valid_auth_hash(user)
# The mock_auth configuration allows you to set per-provider (or default)
# authentication hashes to return during integration testing.
OmniAuth.config.test_mode = true
opts = {
"provider": user.provider,
"uid": user.uid,
"info": {
"email": user.email,
"first_name": user.first_name,
"last_name": user.last_name
},
"credentials": {
"token": 'XKLjnkKJj7hkHKJkk',
"expires": true,
"id_token": 'eyJ0eXAiOiJK1VveHkwaTFBNXdTek41dXAiL.Wz8bwniRJLQ4Fqx_omnGDCX1vrhHjzw',
"token_type": 'Bearer'
}
}
OmniAuth.config.mock_auth[:default] = OmniAuth::AuthHash.new(opts)
end
def mock_invalid_auth_hash
OmniAuth.config.mock_auth[:default] = :invalid_credentials
end
end
我需要我的模块,这样我就可以在我的请求测试中使用它们。
# spec/rails_helper.rb
Dir[Rails.root.join('spec', 'support', '*.rb')].each { |file| require file }
我最近在我的 rails 项目中添加了 Devise 和 CanCanCan 用于身份验证和许可。
结果它破坏了我之前做的大部分验收测试,例如:
resource 'Projects' do
route '/projects?{}', 'Projects collection' do
get 'Return all projects' do
example_request 'list all projects' do
expect(status).to eq 200
我知道为什么这段代码被破坏了:我没有@current_user,CanCan 拒绝了 CanCan::AccessDenied
.
我目前正在尝试对管理员用户进行身份验证,以便我的验收测试能够通过,正如我为管理员定义的 can :manage, :all
。
我偶然发现了很多像我这样的帖子,但没有解决方案有效,因为我找到的所有答案都是为控制器测试而设计的,而且 sign_in 方法显然对他们有用。
到目前为止我尝试了什么:
before(:each) do
sign_in admin
end
NoMethodError:
undefined method `sign_in' for #<RSpec::ExampleGroups::Projects::ProjectsProjectsCollection::GETReturnAllProjects:0x0000000005dc9948>
所以我尝试添加
RSpec.configure do |config|
config.include Devise::TestHelpers
Failure/Error: @request.env['action_controller.instance'] = @controller
NoMethodError:
undefined method `env' for nil:NilClass
据我所知,我不能这样做,因为我不是在控制器范围内进行测试,而是在测试资源,所以我没有@request,也没有@controller。
我做错了什么,如果没有,既然我包含了身份验证和权限,我该如何通过测试?
使用的版本:
cancancan (2.2.0)
devise (4.3.0)
rails (5.1.4)
ruby 2.5.0p0
rspec (3.7.0)
问题与描述的完全一样,我在验收测试中使用Devise helpers没有成功。
我的解决方法是从验收测试适应请求测试。
#spec/requests/projects_spec.rb
require 'rails_helper'
RSpec.describe Project, type: :request do
let!(:admin) { create(:user, is_admin: true) }
let!(:user) { create(:user) }
context 'admin logged in' do
before do
log_in admin
end
it 'Return all projects' do
get projects_path
expect(status).to eq 200
// more tests
end
// more tests
end
context 'Normal user logged in' do
before do
log_in user
end
// more tests
end
log_in
方法来自我自己创建的助手
# spec/support/session_helpers.rb
module SessionHelpers
def log_in(user, valid = true, strategy = :auth0)
valid ? mock_valid_auth_hash(user) : mock_invalid_auth_hash
Rails.application.env_config['omniauth.auth'] = OmniAuth.config.mock_auth[strategy.to_sym]
get user_google_oauth2_omniauth_callback_path
end
end
它只是在 请求级别 存根身份验证(注意 get user_google_oauth2_omniauth_callback_path
这是我的应用程序的身份验证回调)
我的回调是这样配置的:
#app/config/routes.rb
Rails.application.routes.draw do
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
devise_scope :user do
get 'sign_in', to: 'devise/sessions#new', as: :new_user_session
delete 'sign_out', to: 'devise/sessions#destroy', as: :destroy_user_session
end
# app/controllers/users/omniauth_callbacks_controller.rb
module Users
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
include Devise::Controllers::Rememberable
def google_oauth2
@user = User.from_omniauth(request.env['omniauth.auth'])
if @user
sign_in_and_redirect @user
else
redirect_to root_path, notice: 'User not registered'
end
end
// more code
end
end
与其他助手一起(我的提供者是 Omniauth)
#spec/support/omniauth_macros.rb
module OmniauthMacros
def mock_valid_auth_hash(user)
# The mock_auth configuration allows you to set per-provider (or default)
# authentication hashes to return during integration testing.
OmniAuth.config.test_mode = true
opts = {
"provider": user.provider,
"uid": user.uid,
"info": {
"email": user.email,
"first_name": user.first_name,
"last_name": user.last_name
},
"credentials": {
"token": 'XKLjnkKJj7hkHKJkk',
"expires": true,
"id_token": 'eyJ0eXAiOiJK1VveHkwaTFBNXdTek41dXAiL.Wz8bwniRJLQ4Fqx_omnGDCX1vrhHjzw',
"token_type": 'Bearer'
}
}
OmniAuth.config.mock_auth[:default] = OmniAuth::AuthHash.new(opts)
end
def mock_invalid_auth_hash
OmniAuth.config.mock_auth[:default] = :invalid_credentials
end
end
我需要我的模块,这样我就可以在我的请求测试中使用它们。
# spec/rails_helper.rb
Dir[Rails.root.join('spec', 'support', '*.rb')].each { |file| require file }