Testing controller with rspec 3 gives "#routes is nil" - ruby-on-rails

After upgrade my rails app to use rspec 3, the controllers tests broke.
Am I missing something in the rails_helper.rb?
rails_helper.rb
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
Dir[Rails.root.join("spec/support/**/*.rb")].each { |file| require file }
Dir[Rails.root.join("spec/factories/*.rb")].each { |file| require file }
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_base_class_for_anonymous_controllers = false
config.order = "random"
config.include ApplicationHelper
config.include FactoryGirl::Syntax::Methods
config.include ActionController::TestCase::Behavior
config.include Devise::TestHelpers, type: :controller
config.extend ControllerMacros, type: :controller
config.include(MailerMacros)
config.before(:each) { reset_email }
end
users_controller_spec.eb
require 'rails_helper'
describe UsersController do
describe 'has_user' do
let(:student) { FactoryGirl.create(:student) }
it 'not succeeds password' do
get :has_user, { password: 123 }
expect(response).to have_http_status(:unprocessable_entity)
end
end
end
Failures:
1) UsersController has_user not succeeds password
Failure/Error: get :has_user, { password: 123 }
RuntimeError:
#routes is nil: make sure you set it in your test's setup method.
# ./spec/controllers/users_controller_spec.rb:10:in `block (3 levels) in <top (required)>'
Thanks!

Well, missing this line inside rails_helper.rb as documented here
config.infer_spec_type_from_file_location!

Related

Rspec - uninitialized constant error User

I have written tests on Rspec for my model User and get error while starting 'rspec spec'
NameError: uninitialized constant User
my test spec/models/ivd/user_spec.rb
require 'rails_helper'
module Ivd
RSpec.describe User, type: :model do
let(:user) { FactoryGirl.create(:ivd_user, email: "user#example.org", password: "very-secret", admin: true) }
it 'has a valid factory' do
expect(user).to be_valid
end
describe '.find_for_oauth' do
let!(:user) { FactoryGirl.create(:ivd_user) }
describe 'twitter' do
let(:auth) { OmniAuth::AuthHash.new({provider: 'twitter', uid: '12345'})}
context 'user has already authorization' do
it 'return user' do
user.identities.create({provider: 'twitter', uid: '12345'})
expect(User.find_for_oauth(auth)).to eq user
end
end
end
end
end
end
spec_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require 'simplecov'
# SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
SimpleCov.start :rails do
add_filter do |source_file|
source_file.lines.count < 5
end
end
require File.expand_path('../dummy/config/environment.rb', __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'factory_girl_rails'
require 'capybara/poltergeist'
# require 'capybara/rails'
require 'ivd/seeder'
# http://www.thegreatcodeadventure.com/stubbing-with-vcr/
require 'vcr'
require 'webmock/rspec'
WebMock.disable_net_connect!(allow_localhost: true)
# load(Rails.root.join("db", "seeds.rb"))
# Configure capybara for integration testing
# Capybara.default_driver = :rack_test
# Capybara.default_selector = :css
# js_options = {js_errors: false}
# above is sometimes useful to troubleshoot errors with tests
js_options = {}
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, js_options)
end
Capybara.javascript_driver = :poltergeist
# Capybara.ignore_hidden_elements = false
# http://stackoverflow.com/questions/24078768/argumenterror-factory-not-registered
# as per above, need to explicitly set below
FactoryGirl.definition_file_paths = [File.expand_path('../factories', __FILE__)]
FactoryGirl.find_definitions
# Oddly above does not occur if factory_girl_rails is only referrenced in ivd.gemspec
# but not main gemfile
Rails.backtrace_cleaner.remove_silencers!
# Load support files
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
ActionController::Base.prepend_view_path "#{Ivd::Engine.root}/app/themes/default/views/"
RSpec.configure do |config|
# TODO - consider precompiling assets to speed up tests
# config.before(:suite) do
# Rails.application.load_tasks
# Rake::Task["assets:precompile"].invoke
# end
config.include JsonSpec::Helpers
config.warnings = false
config.mock_with :rspec
config.infer_base_class_for_anonymous_controllers = false
config.order = 'random'
# config.include Ivd::ApplicationHelper
# config.include Rails.application.routes.url_helpers
# config.include Ivd::Engine.routes.url_helpers
config.use_transactional_fixtures = false
#
# Make sure the database is clean and ready for test
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
Ivd::Seeder.seed!
end
config.after(:all) do
# http://renderedtext.com/blog/2012/10/10/cleaning-up-after-before-all-blocks/
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, js: true) do
# truncation is slower but more reliable
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
rails_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../dummy/config/environment.rb', __FILE__)
abort('The Rails environment is running in production mode!') if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'rails-controller-testing'
# Add additional requires below this line. Rails is not loaded until this point!
require 'devise'
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.warnings = false
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{Ivd::Engine.root}/spec/fixtures"
# above used by fixture_file_upload
# eg in:
# /Users/etewiah/Ed/sites-2016-oct-ivd/ivd/spec/services/ivd/import_properties_spec.rb
config.infer_spec_type_from_file_location!
config.filter_rails_from_backtrace!
[:controller, :view, :request].each do |type|
config.include ::Rails::Controller::Testing::TestProcess, type: type
config.include ::Rails::Controller::Testing::TemplateAssertions, type: type
config.include ::Rails::Controller::Testing::Integration, type: type
end
# https://github.com/plataformatec/devise/wiki/How-To:-Test-controllers-with-Rails-3-and-4-(and-RSpec)
config.include Devise::Test::ControllerHelpers, type: :controller
config.include FeatureHelpers, type: :feature
config.extend ControllerMacros, type: :controller
# https://github.com/plataformatec/devise/wiki/How-To:-Stub-authentication-in-controller-specs
config.include ControllerHelpers, type: :controller
# https://github.com/plataformatec/devise/wiki/How-To:-sign-in-and-out-a-user-in-Request-type-specs-(specs-tagged-with-type:-:request)
config.include RequestSpecHelpers, type: :request
end
I have model User, which has been inherited from ApplicationRecord.
File .rspec contains only:
--color
--require byebug
--require rails_helper
Is your model itself within the module Ivd? i.e.
module Ivd
class User
If so, you want to be using RSpec.describe Ivd::User rather than wrapping the call in the module.

How to test Devise Login page with RSpec

I'm really annoying this problem about this.
Error is like this.
Despite of declaration of TestLoginController, I always trapped same error.
What should I do?
$ bin/rspec
Running via Spring preloader in process 18113
/Users/noriakitakamizawa/dola/spec/controller/test_login_spec.rb:3:in `<top (required)>': uninitialized constant TestLoginController (NameError)
from /Users/noriakitakamizawa/dola/vendor/bundle/ruby/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/configuration.rb:1435:in `block in load_spec_files'
from /Users/noriakitakamizawa/dola/vendor/bundle/ruby/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/configuration.rb:1433:in `each'
from /Users/noriakitakamizawa/dola/vendor/bundle/ruby/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/configuration.rb:1433:in `load_spec_files'
Here's the code.
spec/controller/test_login_spec.rb
require 'rails_helper'
describe TestLoginController do
login_admin
it "should have a current_user" do
# note the fact that you should remove the "validate_session" parameter if this was a scaffold-generated controller
expect(subject.current_user).to_not eq(nil)
end
it "should get index" do
# Note, rails 3.x scaffolding may add lines like get :index, {}, valid_session
# the valid_session overrides the devise login. Remove the valid_session from your specs
get 'index'
response.should be_success
end
end
spec/rails_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'devise'
require 'rspec/autorun'
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.include Devise::Test::ControllerHelpers, :type => :controller
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
And here's another helper.
spec/spec_helper.rb
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rails'
require 'devise'
Rails.logger = Logger.new(STDOUT)
RSpec.configure do |config|
config.include Rails.application.routes.url_helpers
config.include Capybara::DSL
# for Devise
#config.include Devise::TestHelpers, :type => :controller
#config.include Capybara::DSL
config.include Devise::Test::ControllerHelpers, :type => :controller

Requiring module in Rspec in rails 4 application

I'm trying to include additional Devise helpers in Rspec but am receiving the following error:
rails_helper.rb:56:in `block in <top (required)>': uninitialized constant ControllerMacros (NameError)
Line 56 in rails_helpers.rb is the config.include ControllerMacros line that I have. I've tried to solve this with the solutions posted in other SO posts but can't seem to get this to work. I understand this might be a require order issue but haven't been able to sort out the right order.
rails_helper.rb
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/rails'
require 'capybara/rspec'
require 'devise'
ctiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_spec_type_from_file_location!
config.include Capybara::DSL
config.include Devise::TestHelpers, :type => :controller
config.include ControllerMacros, :type => :controller
end
spec/support/controller_macros.rb
module ControllerMacros
def login_business
before(:each) do
#request.env["devise.mapping"] = Devise.mappings[:business]
business = FactoryGirl.create(:business)
buisness.confirm!
sign_in business
end
end
end
spec/business_account_controller_spec.rb
require 'spec_helper'
require 'rails_helper'
describe BusinessAccountController do
login_business
it "should have current user" do
expect(subject).to_not be_nil
end
end
You need to require it in your rails_helper. I place all of my modules in /spec/support and then put Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } at the top of my rails_helper

Rspec.NoMethodError: undefined method `sign_in' for #<RSpec:

I'm trying to test the admin user in my controller, but when I'm running the test, the shell returns an error :
1) Posts GET /edit_post works for edit post
Failure/Error: sign_in user
NoMethodError:
undefined method `sign_in' for #<RSpec:
posts_spec.rb
describe 'GET /edit_post' do
it 'works for edit post' do
user = FactoryGirl.create(:user)
user.role == 'admin'
sign_in user
end
end
UPD
this is rails_helper.rb
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.include Capybara::DSL
config.include Devise::TestHelpers, type: :controller
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_spec_type_from_file_location!
end
How should I fix this?
Have you included Devise's test helpers, to allow you to use sign_in?
# spec/rails_helper.rb or spec/spec_helper.rb or spec/support/devise.rb
RSpec.configure do |config|
config.include Devise::TestHelpers, type: :controller
end
It's explained here:
http://www.rubydoc.info/github/plataformatec/devise/file/README.md#Test_helpers
I was running into this so I added the following line to test/test_helper.rb and it worked for me.
include Devise::Test::IntegrationHelpers

Capybara JS tests running on separate thread?

I can't seen to get my Capybara tests to work when I put js: true. I think it has something to do with how I'm handling the DB in test. Any help here would be awesome. Here's my error:
Failure/Error: Unable to find matching line from backtrace
ActiveRecord::RecordNotFound:
Couldn't find Executive with 'id'=vid_url [WHERE "users"."type" IN ('Executive')]
My rails_helper.rb
require "codeclimate-test-reporter"
SimpleCov.start do
formatter SimpleCov::Formatter::MultiFormatter[
SimpleCov::Formatter::HTMLFormatter,
CodeClimate::TestReporter::Formatter
]
add_filter '/spec/'
end
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/email/rspec'
require 'capybara/rails'
require 'capybara/webkit/matchers'
require 'database_cleaner'
require 'shoulda/matchers'
require 'webmock/rspec'
# Select Javascript driver
Capybara.javascript_driver = :webkit
# Speed up Devise
Devise.stretches = 1
# Allow net access so we stub out only necessary HTTP requests
WebMock.allow_net_connect!
#WebMock.disable_net_connect!(allow_localhost: true)
# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
# Faster feedback when running all specs
config.fail_fast = true
# FactoryGirl syntax methods
config.include FactoryGirl::Syntax::Methods
config.use_transactional_fixtures = false
config.before(:each) do |example|
DatabaseCleaner.strategy = example.metadata[:js] ? :truncation : :transaction
DatabaseCleaner.start
stub_request(:any, /api.hellosign.com/).to_rack(FakeHelloSign)
end
config.after(:each) do
DatabaseCleaner.clean
end
config.include(Capybara::Webkit::RspecMatchers, type: :feature)
config.infer_spec_type_from_file_location!
# Helpers
config.include Features::ExecutiveHelpers, type: :feature
config.include Features::BuyerHelpers, type: :feature
config.include Features::AccessRequestHelpers, type: :feature
config.include Helpers::SessionHelpers
config.include Helpers::PathHelpers
config.include Helpers::CountHelpers
config.include Helpers::Mailers
config.include Helpers::DebuggingHelpers
config.include Devise::TestHelpers, type: :controller
config.include Requests::UserSessionRequestHelper, type: :request
end

Resources