Reputation: 805
I'm building a rails 4 app. I created a support file to simulate a login. Here are the files
module SpecTestHelper
def login(user)
request.session[:user_id] = user.id
end
def current_user
User.find(request.session[:user_id])
end
end
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
The support file gives an undefined method error. This is part of the error message:
spec/controllers/books_controller_spec.rb:27:in `block in <top (required)>': undefined method `login' for #<Class:0x007f9f83193438> (NoMethodError)
I'm testing CanCan. I know the correct way to test CanCan is testing the Ability but that's already done.
Upvotes: 24
Views: 20157
Reputation: 301
in your spec only add such class or module like following
both files in the path: spec/
# frozen_string_literal: true
require "rails_helper"
class SharedHelper
def defined_action
...
end
end
# frozen_string_literal: true
require "rails_helper"
require_relative "shared_helper"
RSpec.describe "Test request", type: :request do
before(:all) do
SharedHelper.new.defined_action
end
end
Upvotes: 0
Reputation: 519
There can be two files under rspec dir: rails_helper.rb
and spec_helper.rb
. If you want to provide support for rails-dependent classes, you should use rails_helper
to tell rails to load the modules under the 'spec/support'
dir.
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
To declare the shared module, you want to use it inside the config block.
RSpec.configure do |config|
...
config.include <YourModuleName>::<YourClassName>, :type => :controller
...
end
But, if your class doesn't require rails at all, you can load it under spec_helper
, which will not load rails to run the tests.
Refer to this answer and to this reference to learn more about it.
Upvotes: 16
Reputation: 12563
Alternative to the answer provided by @gotva. It's slightly more verbose, but will work in both Rails 3 and 4:
Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
Upvotes: 7
Reputation: 5998
I added this line in spec_helper.rb
and it works in 3rd Rails
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
Maybe another (more pretty) solution exists
Upvotes: 33
Reputation: 24458
Put the login(user)
call within a before
or an it
block, instead of directly within the describe
:
let(:user) do
Fabricate(:user) do
role { Role.find_by_account_type("user") }
end
end
before do
login(user)
end
Upvotes: 2