web-dev-qa-db-ja.com

deviseとrspec-Rails-リクエストタイプのスペック(タイプ::リクエストでタグ付けされたスペック)にユーザーをサインインする方法は?

環境

Rails 4.2.0
Ruby-2.2.1 [ x86_64 ]
devise         3.4.1
rspec-core  3.2.2
rspec-Rails   3.2.1

私の/ spec/Rails_helper.rbには、Deviseヘルパーが含まれていますtype: :controllerおよびtype: :requestでタグ付けされたスペックファイル

spec/Rails_helper.rb

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.

  config.use_transactional_fixtures = false

  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:suite) do
    begin
      DatabaseCleaner.start
      FactoryGirl.lint
    ensure
      DatabaseCleaner.clean
    end
  end

  config.around(:each) do |example|
    DatabaseCleaner.cleaning do
      example.run # ==================> L-60
    end
  end

  config.include FactoryGirl::Syntax::Methods

  # RSpec Rails can automatically mix in different behaviours to your tests
  # based on their file location, for example enabling you to call `get` and
  # `post` in specs under `spec/controllers`.
  #
  # You can disable this behaviour by removing the line below, and instead
  # explicitly tag your specs with their type, e.g.:
  #
  #     RSpec.describe UsersController, :type => :controller do
  #       # ...
  #     end
  #
  # The different available types are documented in the features, such as in
  # https://relishapp.com/rspec/rspec-Rails/docs
  config.infer_spec_type_from_file_location!

  config.include Devise::TestHelpers, type: :controller
  config.include Devise::TestHelpers, type: :request

end

その設定が適切に行われると、type: controller仕様は正常に実行されます。ただし、type: request仕様を実行すると、次のエラーが発生します。

 Failure/Error: Unable to find matching line from backtrace
 NoMethodError:
   undefined method `env' for nil:NilClass
 # /home/.rvm/gems/Ruby-2.2.1@myapp/gems/devise-3.4.1/lib/devise/test_helpers.rb:24:in `setup_controller_for_warden'
 # ./spec/Rails_helper.rb:60:in `block (3 levels) in <top (required)>'
 # /home/.rvm/gems/Ruby-2.2.1@simplyhomeapp/gems/database_cleaner-1.4.1/lib/database_cleaner/generic/base.rb:15:in `cleaning'
 # /home/.rvm/gems/Ruby-2.2.1@simplyhomeapp/gems/database_cleaner-1.4.1/lib/database_cleaner/base.rb:92:in `cleaning'
 # /home/.rvm/gems/Ruby-2.2.1@simplyhomeapp/gems/database_cleaner-1.4.1/lib/database_cleaner/configuration.rb:86:in `block (2 levels) in cleaning'
 # /home/.rvm/gems/Ruby-2.2.1@simplyhomeapp/gems/database_cleaner-1.4.1/lib/database_cleaner/configuration.rb:87:in `call'
 # /home/.rvm/gems/Ruby-2.2.1@simplyhomeapp/gems/database_cleaner-1.4.1/lib/database_cleaner/configuration.rb:87:in `cleaning'
 # ./spec/Rails_helper.rb:59:in `block (2 levels) in <top (required)>'

https://github.com/plataformatec/devise/blob/master/lib/devise/test_helpers.rb#L24 は次のとおりです

def setup_controller_for_warden #:nodoc:
  @request.env['action_controller.instance'] = @controller  # ==================> L-24
end

@requestインスタンスが:requestタイプの仕様で使用できないため、エラーが発生することを認識しています。

Deviseを使用するときに:request type specsでユーザーをサインインするために使用できるヘルパーはありますか?

私は同様の問題を見つけました https://github.com/plataformatec/devise/issues/1114返信 これは次のことを示唆しています:

統合テストを行う場合は、サインインフォームに入力して送信することにより、従来の方法でユーザーにサインインしてください。

しかし、サインインしたユーザーを必要とするスペックの実際のログインをバイパスしたいと思います。

ありがとう。

18
Jignesh Gohel

ここでの人気のある答えは、Devise wikiにも複製されていますが、問題ありませんが、次のようにするのが最も簡単です。

spec/Rails_helper.rb

RSpec.configure do |config|
  # ...
  config.include Devise::Test::IntegrationHelpers, type: :request
end

そして、リクエスト仕様でsign_inを使用するだけです。これは、システム/機能仕様またはRailsシステム/コントローラーテストでinclude Devise::Test::IntegrationHelpersを宣言することと同じです。

5
ybakos