I try to test the login methods for sorcery gem and i get an error.
I user factory girl for factories in my rspec tests.
All i want to do is to add a before method that logs me in, and after that i want to test the actions for my controller.
My spec_helper.rb
require 'factory_girl'
require_relative '../spec/factories/blog.rb'
require_relative '../spec/factories/user.rb'
require_relative '../spec/factories/category.rb'
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
config.include Sorcery::TestHelpers::Rails::Controller, type: :controller
config.include Sorcery::TestHelpers::Rails::Integration, type: :feature
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end
my 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'
RSpec.configure do |config|
config.infer_spec_type_from_file_location!
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
end
the error i get when i run my rspec
Running: spec
/home/user/work/project_name/spec/spec_helper.rb:9:in `block in <top (required)>': uninitialized constant Sorcery::TestHelpers::Rails::Controller (NameError)
My work environment:
Rails 3.2, Ruby 1.9.3, rspec - rails 3.3, sorcery 0.8.2
I found the problem after hours of pain.
The problem was that for sorcery version 0.8.2 you need to add to spec_helper.rb the following code:
RSpec.configure do |config|
.................................(other stuff)
config.include Sorcery::TestHelpers::Rails
..........................(other stuff)
end
and after that use in your specs
#user = User.create
login_user(#user)
Related
Rails 4.2.4, Rspec 3.3.1, shoulda-matchers 3.0.0.
I am getting
#...
358) Participant validations
Failure/Error: it { should ensure_length_of(:coresp_country).is_at_most(255) }
NoMethodError:
undefined method `ensure_length_of' for #<RSpec::ExampleGroups::Participant::Validations:0x0000000f40aec0>
# ./spec/models/participant_spec.rb:100:in `block (3 levels) in <top (required)>'
359) Participant validations company
Failure/Error: it { should ensure_length_of(:company).is_at_most(255) }
NoMethodError:
undefined method `ensure_length_of' for #<RSpec::ExampleGroups::Participant::Validations::Company:0x0000000f414ab0>
# ./spec/models/participant_spec.rb:149:in `block (4 levels) in <top (required)>'
360) Participant validations company declared_type = COMPANY
Failure/Error: it { should validate_presence_of(:company) }
NoMethodError:
undefined method `validate_presence_of' for #<RSpec::ExampleGroups::Participant::Validations::Company::DeclaredTypeCOMPANY:0x0000000f429c58>
#...
And many more failures of this kind (looks like shoulda-matchers do not work).
rails_helper.rb:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'spec_helper'
require 'rspec/rails'
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
Rails.logger.level = 4
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.use_transactional_fixtures = true
config.infer_spec_type_from_file_location!
config.include FactoryGirl::Syntax::Methods
config.include Sorcery::TestHelpers::Rails
config.include Macros::Controller::Security
end
FactoryGirl.reload
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end
spec_helper.rb:
require 'simplecov_helper'
require 'webmock/rspec'
WebMock.disable_net_connect!(allow_localhost: true)
require 'rspec/collection_matchers'
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.filter_run :focus
config.run_all_when_everything_filtered = true
config.disable_monkey_patching!
config.expose_dsl_globally = true
config.default_formatter = 'doc' if config.files_to_run.one?
config.order = :random
Kernel.srand config.seed
end
EDIT
Ok, I think the issue is not with shoulda-matchers, but with active_attr gem, because tests only fails in spec/compositions/api folder, where I use the gem.
shoulda-matchers 3.0 selectively makes its matchers available. I am using ActiveModel matchers which are only mixed into model specs (af98a23).
I had two options to solve the issue:
placing the specs of the models, which use active_attr gem under spec/models folder;
adding type: :model to the top-level describe block for each class in spec/compositions/api folder.
I decided to go with second option and it worked.
Sidenote
Now matchers, which starts with ensure (ensure_inclusion_in, ensure_length_of) are renamed to validate_inclusion_in, validate_length_of (55c8d09).
I put some code in spec/support/request_helpers.rb
module Requests
module JsonHelpers
def json
#json ||= JSON.parse(response.body)
end
end
end
Then I added config line to spec/rails_helper.rb to access that code from my spec.
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'
ActiveRecord::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 Requests::JsonHelpers, :type => :controller
end
So when I run my spec from spec/controller/tasks_controller_spec.rb I get the following error.
/spec/rails_helper.rb:16:in `block in <top (required)>': uninitialized constant Requests (NameError)
How to solve it?
My spec has require 'rails_helper' on the top.
Do you have already added require your support folder?
Add to your spec_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'
# with many helpers
Dir[File.dirname(__FILE__) + "/support/*.rb"].each {|f| require f }
# or only one
# require 'support/request_helpers'
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
# some code here
About spec/support
**Update*: Scroll to very bottom for reproducible error in bare minimum rails app*
I am testing a rails task with Rspec, the fantaskspec gem, and the Factory Girl. When I try to run tests I receive this error:
1) update_account_reverification_table update_account_reverification_table
Failure/Error: account = create(:account, twitter_id: 1234567890)
NoMethodError:
undefined method `create' for #<RSpec::ExampleGroups::UpdateAccountReverificationTable:0x007fda1bd07710>
# ./spec/lib/tasks/account_reverification_spec.rb:18:in `block (2 levels) in <top (required)>'
On line, 18 of my account_reverification_spec.rb file I have this test.
it 'update_account_reverification_table' do
# binding.pry
account = create(:account, twitter_id: 1234567890)
Account.first.reverification.twitter_reverification_sent_at.must_equal Time.now
Account.first.reverification.twitter_reverified.must_equal true
end
I have also tried this variation but the test continues to fail:
account = FactoryGirl.create(:account, twitter_id: 1234567890)
However I receive a different error:
1) update_account_reverification_table update_account_reverification_table
Failure/Error: account = FactoryGirl.create(:account, twitter_id: 1234567890)
ArgumentError:
Factory not registered: account
Here is my spec_helper.rb and my rails_helper.rb
require 'fantaskspec'
require 'factory_girl_rails'
require 'pry-rails'
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.infer_rake_task_specs_from_file_location!
end
and rails_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.include FactoryGirl::Syntax::Methods
FactoryGirl.definition_file_paths = [File.expand_path('../factories', __FILE__)]
FactoryGirl.find_definitions
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
end
Note that I have these lines in my rails_helper.rb file:
config.include FactoryGirl::Syntax::Methods
FactoryGirl.definition_file_paths = [File.expand_path('../factories', __FILE__)]
FactoryGirl.find_definitions
I grabbed this from a previous answer on a different problem referenced here Specific config problem Any ideas?
-----EDIT #2------
I have created a brand new basic example app to help figure out where this problem could potentially be. I have followed the instructions to set up my directory and tree structure using these documentation links.
Rspec
Factory Girl Rails
Fantaskspec
Tutorial on Rspec and Fantaskspec
Directory tree structure:
spec
- factories
- accounts.rb
- lib
- tasks
- account_reverification_spec.rb
- support
- factory_girl.rb
- rails_helper.rb
- spec-helper.rb
Contents of spec/support/factory_girl.rb
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
end
Contents of spec/factories/accounts.rb
FactoryGirl.define do
sequence :account_login do |n|
"login-#{ n }"
end
factory :account do
sequence :email do |n|
"someone#{n}#gmail.com"
end
email_confirmation { |account| account.send :email }
url { Faker::Internet.url }
login { generate(:account_login) }
password { Faker::Internet.password }
password_confirmation { |account| account.send(:password) }
current_password { |account| account.send(:password) }
twitter_account 'openhub'
name { Faker::Name.name + rand(999_999).to_s }
about_raw { Faker::Lorem.characters(10) }
activated_at { Time.current }
activation_code nil
country_code 'us'
email_master true
email_kudos true
email_posts true
end
end
Contents of spec/lib/tasks/account_reverification_spec.rb
require 'rails_helper'
RSpec.describe 'update_account_reverification_table' do
let(:task_name) { 'update_account_reverification_table' }
it 'correct task is called' do
expect(subject).to be_a(Rake::Task)
expect(subject.name).to eq("update_account_reverification_table")
expect(subject).to eq(task)
end
it 'update_account_reverification_table' do
account = create(:account, twitter_id: 1234567890)
end
end
Contents of rails_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'fantaskspec'
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
Rails.application.load_tasks
config.infer_rake_task_specs_from_file_location!
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
end
Contents of spec_helper.rb
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end
Try adding the following line to your spec_helper.rb file:
require 'factory_girl'
Also, add these lines to your spec_helper.rb:
FactoryGirl.definition_file_paths.clear
FactoryGirl.definition_file_paths << File.expand_path('../factories', __FILE__)
FactoryGirl.find_definitions
and remove them from RSpec.configure do |config| block.
Also, make sure you defined your factories in the correct file. It should be defined in factories.rb in your test folder (spec) if you use rspec.
Update
FactoryGirl.definition_file_paths.clear
FactoryGirl.definition_file_paths << "./spec/factories"
FactoryGirl.find_definitions
These lines should go to your spec/support/factory_girl.rb file and remove them from anywhere else.
Also, add the following in your spec_helper.rb:
config.before(:all) do
FactoryGirl.reload
end
In your spec_helper.rb the Rspec.configure block should look like this:
RSpec.configure do |config|
config.mock_with :rspec
config.run_all_when_everything_filtered = true
config.filter_run :focus
config.include FactoryGirl::Syntax::Methods
end
Update
Add this to your rails_helper.rb:
require_relative 'support/factory_girl.rb'
And then it should work.
After installing Capybara, I get the error:
NoMethodError: undefined method `join' for nil:NilClass
whenever I try to run rspec.
I've been trying to add and remove different requirements, but nothing seems to work. Does anyone have any idea what's happening?
spec_helper.rb
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.filter_run :focus
config.run_all_when_everything_filtered = true
config.disable_monkey_patching!
config.warnings = true
if config.files_to_run.one?
config.default_formatter = 'doc'
end
config.profile_examples = 10
config.order = :random
Kernel.srand config.seed
config.include FactoryGirl::Syntax::Methods
#FactoryGirl.definition_file_paths = [File.expand_path('../factories', __FILE__)]
config.warnings = false
config.infer_spec_type_from_file_location!
config.include SpecTestHelper, :type => :controller
config.include Capybara::DSL
end
Capybara.default_driver = :selenium
rails_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require 'spec_helper'
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_spec_type_from_file_location!
end
And for all of my spec files I include:
require 'spec_helper'
Please help!
Update:
Here is the backtrace:
NoMethodError: undefined method `join' for nil:NilClass
(root) at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/capybara-2.4.4/lib/capybara/rails.rb:15
require at org/jruby/RubyKernel.java:1071
require at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/activesupport-3.2.21/lib/active_support/dependencies.rb:251
load_dependency at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/activesupport-3.2.21/lib/active_support/dependencies.rb:236
require at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/activesupport-3.2.21/lib/active_support/dependencies.rb:251
(root) at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/rspec-rails-3.2.1/lib/rspec/rails/vendor/capybara.rb:1
require at org/jruby/RubyKernel.java:1071
require at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/activesupport-3.2.21/lib/active_support/dependencies.rb:251
load_dependency at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/activesupport-3.2.21/lib/active_support/dependencies.rb:236
require at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/activesupport-3.2.21/lib/active_support/dependencies.rb:251
(root) at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/rspec-rails-3.2.1/lib/rspec/rails/vendor/capybara.rb:7
require at org/jruby/RubyKernel.java:1071
(root) at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/rspec-rails-3.2.1/lib/rspec/rails.rb:1
require at org/jruby/RubyKernel.java:1071
(root) at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/rspec-rails-3.2.1/lib/rspec/rails.rb:13
each at org/jruby/RubyArray.java:1613
(root) at /Users/ssuhli200/Downloads/cimport/spec/spec_helper.rb:1
(root) at /Users/ssuhli200/Downloads/cimport/spec/spec_helper.rb:5
each at org/jruby/RubyArray.java:1613
(root) at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/rspec-core-3.2.3/lib/rspec/core/configuration.rb:1
requires= at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/rspec-core-3.2.3/lib/rspec/core/configuration.rb:1181
requires= at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/rspec-core-3.2.3/lib/rspec/core/configuration.rb:1181
process_options_into at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/rspec-core-3.2.3/lib/rspec/core/configuration_options.rb:110
process_options_into at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/rspec-core-3.2.3/lib/rspec/core/configuration_options.rb:109
configure at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/rspec-core-3.2.3/lib/rspec/core/configuration_options.rb:22
setup at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/rspec-core-3.2.3/lib/rspec/core/runner.rb:96
load at org/jruby/RubyKernel.java:1087
run at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/gems/rspec-core-3.2.3/lib/rspec/core/runner.rb:85
eval at org/jruby/RubyKernel.java:1107
(root) at /Users/ssuhli200/.rvm/gems/jruby-1.7.18#cimport/bin/jruby_executable_hooks:15
You need to require rails_helper not spec_helper. The problem is that Capybara is calling Rails.root.join before your Rails app has fired up (which is taken care of in your Rails helper).
My Turnip test is working normally, but does not work when using spork.
I debugged with pry and I found that a missing User(class constant) causes the error.
What should I do to fix?
# working (good)
bundle exec rspec spec/acceptance/features/*
# not work (bad)
bundle exec rspec spec/acceptance/features/* --drb
Here is the error when I run with the --drb option.
Failure/Error: Give a user logged in:
NameError:
wrong constant name #<Module:0x007fd40a19c680>
# spec/acceptance/steps/user_steps.rb:8:in `block (2 levels) in <module:UserSteps>'
# spec/acceptance/steps/user_steps.rb:7:in `each'
This is my spec_helper.rb.
require 'rubygems'
require 'spork'
#uncomment the following line to use spork with the debugger
#require 'spork/ext/ruby-debug'
Spork.prefork do
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/dsl'
require 'capybara/rspec'
require 'capybara/rails'
require 'turnip'
require 'turnip/capybara'
require 'shoulda/matchers/integrations/rspec'
# 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}
Dir.glob("spec/**/*steps.rb") { |f| load f, true }
WebMock.disable_net_connect!(:allow_localhost => true)
Capybara.run_server = true
Capybara.app_host = 'http://localhost'
Capybara.server_port = 8000
Capybara.default_selector = :css
Capybara.javascript_driver = :webkit
OmniAuth.config.test_mode = true
RSpec.configure do |config|
# ## Mock Framework
config.mock_with :rr
config.infer_base_class_for_anonymous_controllers = false
config.order = "random"
config.include FactoryGirl::Syntax::Methods
config.include Capybara::DSL, turnip: true
config.include Rails.application.routes.url_helpers
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
config.before(:each, js: true) do
headless = Headless.new
headless.start
end
end
end
Spork.each_run do
# This code will be run each time you run your specs.
end
This is user_steps.rb.
1. require_relative 'helper_steps'
2.
3. module UserSteps
4. include HelperSteps
5.
6. step 'users are registered :' do |table|
7. table.hashes.each do |row_hash|
8. create(:user, class_params_by_row_hash(User, row_hash))
9. end
10. end
11. end
rails 3.2.13
rspec-rails 2.11.0
rspec 2.11.0
turnip 1.1.0
spork 1.0.0rc3
I'm not sure why this problem occurs, but you can prevent it from happening. If you're wrapping your steps in modules, you don't need to pass the true wrap parameter to load. Change:
Dir.glob("spec/**/*steps.rb") { |f| load f, true }
to:
Dir.glob("spec/**/*steps.rb") { |f| load f }
This prevents this error for me.
Reference: http://www.ruby-doc.org/core-2.1.2/Kernel.html#method-i-load