shoulda-matchers: Broken Rspec Integration 3.0.0

Hi, I just installed this gem and following the readme, but. it gives this error while running rspec. uninitialized constant Shoulda (NameError)

This is my rails_helper.rb

Shoulda::Matchers.configure do |config|

    config.integrate do |with|
      # Choose a test framework:
      with.test_framework :rspec

      # Or, choose the following (which implies all of the above):
      with.library :rails
    end

  end

Any idea?

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 23

Commits related to this issue

Most upvoted comments

I was having same issues. Solution: I had a group “test” in the Gemfile for which the shoulda-matcher was defined, but was working all the time on development environment. Just changed the gem definition to :development, :test group and bundle install again. Worked like a charm.

The shoulda-matchers configuration should not be added to spec_helper, but to rails_helper.

When you run the rspec executable, because you have --require spec_helper in .rspec, RSpec will load spec_helper first before it tries to run any files. The goal of spec_helper is to set up any tests that don’t need Rails to run; therefore, it will not load your Rails environment or automatically require any gems in your Gemfile, including shoulda-matchers. This is why the Shoulda constant isn’t available. To fix this, move that configuration block into rails_helper (which does set up a Rails environment) and everything should be golden.

You need add those new contents to rails_helper.rb instead of replacing the original code rails_helper should be like this (it works for me):

# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
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 'rspec/rails'
# Add additional requires below this line. Rails is not loaded until this point!
require 'database_cleaner'
 
# [...]

Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :rspec
    with.library :rails
  end
end
 

# end
# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
# run as spec files by default. This means that files in spec/support that end
# in _spec.rb will both be required and run as specs, causing the specs to be
# run twice. It is recommended that you do not name files matching this glob to
# end with _spec.rb. You can configure this pattern with the --pattern
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
#
# The following line is provided for convenience purposes. It has the downside
# of increasing the boot-up time by auto-requiring all files in the support
# directory. Alternatively, in the individual `*_spec.rb` files, manually
# require only the support files necessary.
#
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

# Checks for pending migrations and applies them before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
  config.include RequestSpecHelper, type: :request
  # [...]
  
  config.include FactoryGirl::Syntax::Methods
 
  # start by truncating all the tables but then use the faster transaction strategy the rest of the time.
  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
    DatabaseCleaner.strategy = :transaction
  end
 
  # start the transaction strategy as examples are run
  config.around(:each) do |example|
    DatabaseCleaner.cleaning do
      example.run
    end
  end
  # [...]
  # 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

  # RSpec Rails can automatically mix in different behaviours to your tests
  # based on their file location, for example enabling you to call `get` and
  # `post` in specs under `spec/controllers`.
  #
  # You can disable this behaviour by removing the line below, and instead
  # explicitly tag your specs with their type, e.g.:
  #
  #     RSpec.describe UsersController, :type => :controller do
  #       # ...
  #     end
  #
  # The different available types are documented in the features, such as in
  # https://relishapp.com/rspec/rspec-rails/docs
  config.infer_spec_type_from_file_location!

  # Filter lines from Rails gems in backtraces.
  config.filter_rails_from_backtrace!
  # arbitrary gems may also be filtered via:
  # config.filter_gems_from_backtrace("gem name")
end

I’ve had the same issue, the only way I’ve been able to solve the issue is to use the full line, RAILS_ENV=test bundle exec rspec

EDIT: Changing the location to group :development, :test also works, but this seems odd to me. The test suite feels like it should be in test only. I guess it is just a matter of semantics.

@mcmire, I am having this issue. I’m using Ruby 2.3.4p301 (2017-03-30 revision 58214) [x86_64-darwin16] and Rails 5.1.3 shoulda-matchers are included in my gemfile like this:

group :development, :test do
  gem 'shoulda-matchers', '~> 3.1'

(I did have shoulda-matchers line in group :test do instead earlier, with the same error.

Here are the errors:

♥♥♥♥♥♥♥♥♥♥♥♥ bundle exec rspec

An error occurred while loading ./spec/models/meal_spec.rb.
Failure/Error:
  Shoulda::Matchers.configure do |config|
    config.integrate do |with|
      with.test_framework :rspec
      with.library :rails
    end
  end

NameError:
  uninitialized constant Shoulda
# ./spec/rails_helper.rb:6:in `<top (required)>'
# ./spec/models/meal_spec.rb:1:in `require'
# ./spec/models/meal_spec.rb:1:in `<top (required)>'

An error occurred while loading ./spec/models/user_spec.rb.
Failure/Error:
  Shoulda::Matchers.configure do |config|
    config.integrate do |with|
      with.test_framework :rspec
      with.library :rails
    end
  end

NameError:
  uninitialized constant Shoulda
# ./spec/rails_helper.rb:6:in `<top (required)>'
# ./spec/models/user_spec.rb:1:in `require'
# ./spec/models/user_spec.rb:1:in `<top (required)>'
No examples found.


Finished in 0.00019 seconds (files took 0.11059 seconds to load)
0 examples, 0 failures, 2 errors occurred outside of examples

Here is my rails_helper:

# require database cleaner at the top level
require 'database_cleaner'

# [...]
# configure shoulda matchers to use rspec as the test framework and full matcher libraries for rails
Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :rspec
    with.library :rails
  end
end

# [...]
RSpec.configuration do |config|
  # [...]
  # add `FactoryGirl` methods
  config.include FactoryGirl::Syntax::Methods

  # start by truncating all the tables but then use the faster transaction strategy the rest of the time.
  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
    DatabaseCleaner.strategy = :transaction
  end

  # start the transaction strategy as examples are run
  config.around(:each) do |example|
    DatabaseCleaner.cleaning do
      example.run
    end
  end
  # [...]
end

Ah yes. I think my problem is I added the configuration at spec_helper.rb

Yes. It is a fresh install.

group :test do

  gem 'rspec-rails', '~> 3.0'
  gem 'shoulda-matchers', '~> 3.0.0'
  gem 'factory_girl_rails'
  gem 'faker'

end

I’m not sure why you’d be getting that error. I’m assuming you have shoulda-matchers in your Gemfile?