Подтвердить что ты не робот

Rails, Devise, Rspec: Undefined метод 'sign_in'

Я пытаюсь написать Rspec-тесты в Rails, используя вспомогательные методы Devise для входа и выхода. Метод sign_in не работает. Тем не менее, он работал раньше, до появления изменений в приложении.

Вещи, которые я пробовал:

  • Я включаю тестовые помощники в Rspec.configure.
  • Использование Warden login_as
  • Очистка кеша Rails.
  • Как избавиться от Capybara, чтобы узнать, вызвали ли это проблему.
  • Я не устанавливаю сеанс явно в своих спецификациях контроллера (например, no 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

заводы/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

Спасибо заранее.

4b9b3361

Ответ 1

Вы недавно обновились до RSpec 3, как я? Это от документации RSpec 3:

Автоматическое добавление метаданных Версия RSpec до 3.0.0 автоматически добавляет метаданные к спецификациям на основе их расположение в файловой системе. Это было смущает новых пользователей, а не желательно для некоторых пользователей ветеранов.

В RSpec 3 это поведение должно быть явно включено:

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

Поскольку это предполагаемое поведение настолько распространено в учебниках, значение по умолчанию конфигурация, генерируемая rails, генерирует rspec: install позволяет это.

Если вы следуете приведенной выше канонической структуре каталогов и настроен infer_spec_type_from_file_location!, RSpec будет автоматически включить правильные вспомогательные функции для каждого типа.

После добавления этого фрагмента конфигурации мне больше не нужно указывать тип спецификации (например, type: :controller).

Ответ 2

Я понял решение. Я явно определил контроллер Описать блок как тип контроллера.

describe OrderItemsController, :type => :controller do

Я до сих пор не понимаю, почему этот код работал раньше, но теперь нуждается в этом (казалось бы, избыточном) явном объявлении. Несмотря ни на что, я был бы рад узнать, что здесь произошло. Спасибо!

Ответ 3

Я могу предоставить вам пример (работает для меня - rspec/capybara/simplecov и т.д.)

спецификации /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

спецификации/интеграция/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

Я надеюсь, что все будет хорошо:) Я думаю, что ваша проблема отсутствует Помощники по тестированию...

Ответ 4

Вы можете использовать помощник Devise в файле spec/spec_helper.rb:

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

Ответ 5

Для Rails 5 и Rspec 3 вам нужно добавить это в свой spec_helper.rb

config.include Devise:: Test:: ControllerHelpers, введите:: controller