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
Спасибо заранее.
Ответы
Ответ 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