Как включить файл поддержки в rails 4 для rspec?

Я создаю приложение rails 4, и у меня возникла странная проблема: файл поддержки, который я создал для имитации входа, дает мне ошибку метода undefined.

Вот файлы

#spec/support/spec_test_helper.rb
module SpecTestHelper
  def login(user)
    request.session[:user_id] = user.id
  end

  def current_user
    User.find(request.session[:user_id])
  end
end

#spec_helper.rb

config.include SpecTestHelper, :type => :controller

и в спецификации контроллера

describe BooksController, "user role" do

  user = Fabricate(:user) do
    role { Role.find_by_account_type("user") }
  end

  login(user)
end

BTW Я тестирую CanCan; Я знаю, что правильный способ проверить, что CanCan тестирует способность, но уже сделал:)

Это часть сообщения об ошибке:

spec/controllers/books_controller_spec.rb:27:in `block in <top (required)>': undefined method `login' for #<Class:0x007f9f83193438> (NoMethodError)

Ответ 1

Поместите вызов login(user) в блок before или it вместо прямого в describe:

let(:user) do
  Fabricate(:user) do
    role { Role.find_by_account_type("user") }
  end
end

before do
  login(user)
end

Ответ 2

Я добавил эту строку в spec_helper.rb и работает в 3rd Rails

Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

Возможно, существует еще одно (более красивое) решение.

Ответ 3

Я использую версию 4.2.4 рельсов, и вчера я боролся за добавление файла в папку поддержки. Проблема заключалась в том, что я не заметил различной цели двух файлов в каталоге rspec. У меня есть как rails_helper.rb, так и spec_helper.rb. Если вы хотите предоставить поддержку для классов, зависящих от рельсов, вы должны использовать rails_helper, чтобы указать rails для загрузки модулей в директории spec/support

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

и объявить общий модуль, который вы хотите использовать внутри блока конфигурации.

RSpec.configure do |config|
  ...
  config.include <YourModuleName>::<YourClassName>, :type => :controller
  ...
end

Но если ваш класс вообще не требует рельсов, вы можете загрузить его под spec_helper, который не будет загружать рельсы для запуска тестов. Обратитесь к этому ответу и эта ссылка, чтобы узнать больше об этом.

Ответ 4

Альтернатива ответам, предоставленным @gotva. Он немного более подробный, но будет работать как в Rails 3, так и в 4:

Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}