请求规范中的存根身份验证 [英] Stub authentication in request specs
问题描述
我正在寻找此,但在要求中提供。我需要登录并注销 double
或 instance_double
进行设计,而不是实际的ActiveModel / ActiveRecord。
I'm looking for the way to do this but in request specs. I need to log in and log out a double
or instance_double
to Devise instead of an actual ActiveModel/ActiveRecord.
通过使用Wiki页面中的代码:
By using the code in the wiki page:
module RequestSpecHelpers
def sign_in(user = double('user'))
if user.nil?
allow(request.env['warden']).to receive(:authenticate!).and_throw(:warden, {:scope => :user})
allow(controller).to receive(:current_user).and_return(nil)
else
allow(request.env['warden']).to receive(:authenticate!).and_return(user)
allow(controller).to receive(:current_user).and_return(user)
end
end
end
我得到这个错误: nil:NilClass的未定义方法'env'
我看到了此问题和此Wiki ,但是如果我想使用两倍的用户,那么这两个就行不通了。我使用的是最后一个,可以与实际用户一起正常使用,但如果没有,则不能登录。
I saw this question and this wiki, but if I want to use doubles of the user those two don't work. I was using the last one, works fine with a real user but with a double it doesn't log it in.
测试:
RSpec.describe 'new shipment', type: :request do
describe 'authenticated as user' do
before do
@user = double(:user, id: 1, email: 'user@gmail.com', password: 'password',
id_card: '4163649-1', first_name: 'Jane', last_name: 'Doe')
sign_in @user
end
end
end
如果我包括:
RSpec.configure do |config|
config.include Devise::TestHelpers, :type => :requests
end
我收到此错误:
Failure/Error: @request.env['action_controller.instance'] = @controller
NoMethodError:
undefined method `env' for nil:NilClass
# /root/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/devise-4.3.0/lib/devise/test/controller_helpers.rb:40:in `setup_controller_for_warden'
弗雷德里克的问题张答案
如果我这样做, login_as
方法不会失败,但实际上不会记录用户in。因此,当我尝试访问具有 before_action:authenticate_user!
回调的路径时,它将失败。
Problem with Frederick Cheung answer
If I do that the login_as
method doesn't fail but it doesn't really log the user in. So when I try to access a path that has a before_action :authenticate_user!
callback it fails.
此处是我根据他的答案得出的代码:
Here is my code based on his answer:
require 'rails_helper'
RSpec.describe 'new shipment', type: :request do
describe 'authenticated as user' do
include Warden::Test::Helpers
before(:each) do
Warden.test_mode!
#stub more methods as needed by the pages you are testing
user = instance_double(User, to_key: 1, authenticatable_salt: 'example')
login_as(user, scope: 'user')
end
it 'returns 200 Ok' do
get new_shipment_path
expect(response).to have_http_status(:ok)
end
end
end
这是运行 rspec
:
1) new shipment authenticated as user returns 200 Ok
Failure/Error: expect(response).to have_http_status(:ok)
expected the response to have status code :ok (200) but it was :found (302)
# ./spec/requests/shipments_requests_spec.rb:41:in `block (3 levels) in <top (required)>'
看到而不是允许我访问它重定向我的路径,这是不允许用户访问路径时的常见行为。
As you can see instead of allowing me to access the path it redirects me, this is the usual behavior when the user is not allowed to access the path.
我更改了保存在数据库中的实际 User
的 instance_double
,此方法正常工作:
It I change the instance_double
for a real User
saved in the database this approach works correctly:
# only changed this line in the before hook
user = User.create(email: 'user@gmail.com', password: 'password',id_card: '4163649-1', first_name: 'Jane', last_name: 'Doe')
结果:
Finished in 3.23 seconds (files took 33.47 seconds to load)
1 example, 0 failures
推荐答案
听起来您正在使用Devise 3.x(由于在设计4中将 Devise :: TestHelpers
重命名,所以 Devise :: TestHelpers
仅设计用于控制器规格。 。
It sounds like you're using Devise 3.x ( since Devise::TestHelpers
was renamed in devise 4), Devise::TestHelpers
is only designed to work with controller specs.
如果您可以升级到装置4,则它具有用于请求规范和控制器测试的独立帮助器。这只是看守提供的的一个非常薄的包装,它隐藏了所有混乱
If you can upgrade to devise 4, it has separate helpers for request specs and controller tests. This is just a very thin wrapper around what warden provides, which hides all the messing around with env.
使用双精度时会带来一些额外的复杂性-您需要找出各种方法来设计可能无法实现的调用。
There are some extra complications when using a double - you need to stub out various methods devise calls that you might not realise.
以下内容对我有用
describe 'example' do
include Warden::Test::Helpers
before(:each) do
Warden.test_mode!
#stub more methods as needed by the pages you are testing
user = instance_double(User, to_key: 1, authenticatable_salt: 'example')
login_as(user, scope: 'user')
end
end
这篇关于请求规范中的存根身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!