web-dev-qa-db-ja.com

Rails、Devise、Rspec:未定義のメソッド 'sign_in'

サインインとサインアウトにDeviseヘルパーメソッドを使用して、RailsでRspecテストを記述しようとしています。 sign_inメソッドが機能していません。ただし、それはアプリに多数の変更が加えられる前の、以前は機能していました。

私が試したこと:

  • Rspec.configureにテストヘルパーを含めています。
  • Wardenのlogin_asを使用する
  • Railsキャッシュをクリアします。
  • それが問題を引き起こしていたかどうかを確認するためにカピバラを取り除く
  • コントローラの仕様でセッションを明示的に設定していません(例:valid_sessionなし)

これまでのところ、サイコロはありません。サインインしたユーザーでコントローラーをテストするために、別の方法を実行する必要がありますか?

エラーメッセージ:

 OrderItemsController GET #index renders the :index view
 Failure/Error: sign_in :admin
 NoMethodError:
      undefined method `sign_in' for #  <RSpec::ExampleGroups::OrderItemsController_2::GETIndex:0x00000102c002d0>
 # ./spec/controllers/order_items_controller_spec.rb:6:in `block (2 levels) in <top (required)>'

コントローラースペック

require 'spec_helper'

describe OrderItemsController do
    before (:each) do
        admin = create(:admin)
        sign_in :admin
    end

    describe "GET #index" do
        it "renders the :index view" do
            get :index
            expect( response ).to render_template :index
        end
    end
end

spec_helper.rb

require 'rspec/Rails'
require 'capybara/rspec'

RSpec.configure do |config|

  config.include ApplicationHelper
  config.include ControllersHelper
  config.include UsersHelper
  config.include Devise::TestHelpers, type: :controller
  config.include FactoryGirl::Syntax::Methods

end

Gemfile

group :development, :test do
    gem 'rspec-Rails', '~> 3.0.0.beta'
    gem 'capybara'
    gem 'factory_girl_Rails'
    gem 'faker'
    gem 'dotenv-Rails'
    gem 'guard'
    gem 'guard-annotate'
    gem 'guard-rspec', require: false
    gem 'guard-livereload', require: false
    gem 'foreman'
end

factorys/user.rb

FactoryGirl.define do

    factory :user do
        first                   { Faker::Name.first_name }
        last                    { Faker::Name.last_name }
        email                   { Faker::Internet.email }
        admin                   false
        password                "secrets1"
        password_confirmation   "secrets1"
        confirmed_at            Date.today

        factory :admin do
            admin               true
        end
    end
end

前もって感謝します。

32
steel

最近、私と同じようにRSpec 3にアップグレードしましたか?これは RSpec 3のドキュメント からです:

メタデータの自動追加3.0.0より前のバージョンのRSpecでは、ファイルシステム上の場所に基づいてメタデータが仕様に自動的に追加されました。これは、新しいユーザーを混乱させるだけでなく、一部のベテランユーザーにとっても望ましくありませんでした。

RSpec 3では、この動作を明示的に有効にする必要があります。

​# spec/Rails_helper.rb
RSpec.configure do |config|
    config.infer_spec_type_from_file_location!
end

この想定される動作はチュートリアルで非常に一般的であるため、Rails generate rspec:installによって生成されるデフォルトの構成により、これが可能になります。

上記の正規のディレクトリ構造に従い、infer_spec_type_from_file_location!を設定した場合、RSpecは自動的に各タイプの正しいサポート関数を含めます。

その構成スニペットを追加した後、スペックタイプを指定する必要がなくなりました(例:type: :controller)。

29
Tyler Collier

私は解決策を見つけました。コントローラーのDescribeブロックをコントローラータイプとして明示的に定義しました。

describe OrderItemsController, :type => :controller do

私はまだこのコードが以前に機能した理由を理解していませんが、今はこの(一見冗長に見える)明示的な宣言が必要です。とにかく、ここで何が起こったかを学んでいただければ幸いです。ありがとう!

8
steel

私はあなたに例を提供することができます(私にとってはうまくいきます-rspec/capybara/simplecovなど)

spec/spec_helper.rb

 require 'capybara/rspec'
 require 'capybara/Rails'

 RSpec.configure do |config|
  config.use_transactional_fixtures = true

  config.infer_base_class_for_anonymous_controllers = false

  config.include FactoryGirl::Syntax::Methods
  config.include Devise::TestHelpers, type: :controller
  config.include Capybara::DSL
  config.include Warden::Test::Helpers
  config.include Rails.application.routes.url_helpers
end

spec/integration/user_flow_spec.rb

require 'spec_helper'

feature 'Verify contract' do
  # Create employee
  let(:employee) { create(:employee) }
  let (:book) { create(:book) }

  # Sign in employee before each test!
  before :each do
    login_as employee, scope: :user
  end

  scenario 'create book' do
    # Visit Index and click to create
    visit employee_books_path
    click_link 'Create'
    expect(current_path).to eq(employee_books_path)
  end
end

私はそれが大丈夫であることを願っています:)あなたの問題にはWardenテストヘルパーが欠けていると思います...

6
Jan Strnádek

ファイルspec/spec_helper.rbでDeviseヘルパーを使用できます。

RSpec.configure do |config|
   config.include Devise::TestHelpers, type: :controller
end
4
aarkerio

Rails 5およびRspec 3の場合、これをspec_helper.rbに追加する必要があります

config.include Devise :: Test :: ControllerHelpers、タイプ::controller

0
Andrey