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).
Related
I'm trying to set up Rspec and Shoulda-Matchers, but for some reason I get this error:
NoMethodError:
undefined method `validate_presence_of' for #RSpec::ExampleGroups::AdCampaign::Validations:0x000000062a2b90>
Failure/Error: it { should have_many :advertisements }
expected # to respond to has_many?
NoMethodError:
undefined method `belong_to' for #RSpec::ExampleGroups::AdCampaign::Associations:0x0000000686d8e0>
It seems that I tried every answer from stackoverflow and github issues, and nothing helps.
Maybe you could help me to find out what I'm doing wrong?
Here's 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 'rspec/rails'
require 'shoulda/matchers'
require 'spec_helper'
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.filter_rails_from_backtrace!
end
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end
and here's my spec_helper.rb:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
require 'shoulda/matchers'
require 'database_cleaner'
require 'capybara/rspec'
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
RSpec.configure do |config|
config.include Rails.application.routes.url_helpers
config.include FactoryGirl::Syntax::Methods
config.include(Shoulda::Matchers::ActiveModel, type: :model)
config.include(Shoulda::Matchers::ActiveRecord, type: :model)
# config.include Shoulda::Matchers::ActiveRecord, type: :model
# config.include Devise::TestHelpers, type: :controller
config.order = 'random'
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
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
heer's the spec file with my tests:
require 'rails_helper'
RSpec.describe AdCampaign, type: :model do
describe 'validations' do
it { should validate_presence_of :shop }
it { should validate_presence_of :description }
end
describe 'associations' do
it { should belong_to :shop }
it { should have_many :advertisements }
it { should have_one :recipient_list }
end
end
and here's the model I'm trying to test:
class AdCampaign < ActiveRecord::Base
belongs_to :shop
has_many :advertisements
has_one :recipient_list
validates :shop, :description, presence: true
end
I've tried placing Shoulda::Matchers.configure do... in both rails_helper.rb and spec_helper.rb.
And in my gem file I have shoulda-matchers gem like this:
group :development, :test do
gem 'shoulda-matchers', require: false
end
Could you please help me with setting up shoulda-matchers and rspec? What am I doing wrong here?
I had a similar problem! Me helped this:
# Gemfile
group :test do
gem "shoulda-matchers", require: false
end
And this is to add to the top rspec_helper.rb
require 'shoulda-matchers'
require "bundler/setup"
::Bundler.require(:default, :test)
::Shoulda::Matchers.configure do |config|
config.integrate do |with|
# Choose a test framework:
with.test_framework :rspec
#with.test_framework :minitest
#with.test_framework :minitest_4
#with.test_framework :test_unit
# Choose one or more libraries:
with.library :active_record
with.library :active_model
#with.library :action_controller
# Or, choose the following (which implies all of the above):
#with.library :rails
end
end
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)
**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