请求规范中的存根身份验证 [英] Stub authentication in request specs

查看:54
本文介绍了请求规范中的存根身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找,但在要求中提供。我需要登录并注销 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_asmethod 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆