I tried to use shoulda-matchers to test the association between models. However, it always show Error:
TakingTest#test_belongs_to:
NoMethodError: undefined method belong_to' for #<TakingTest:0x00007fc14b8e64a8>
test/models/taking_test.rb:8:inblock in '
I checked other answer, most of them are at least 4 years ago. Does it still work with rails 6.0?
ruby '2.6.5'
rails', '~> 6.0.2'
gem file
group :development, :test do
gem 'rspec-rails'
end
group :test do
gem 'shoulda', '~> 3.5'
gem 'shoulda-matchers'
end
spec/rails_helper.rb:
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end
test/models/taking_test.rb
class TakingTest < ActiveSupport::TestCase
test "belongs to" do
should belong_to(:students)
end
end
Having both a spec directory and a test directory could be causing your problem. IMO, there should only ever be spec or test for a every project, never both.
Usually, test files begin with an include for the test_helper.rb file.
require 'test_helper'
Instead of a test_helper, you've got a spec_helper.
Try moving the Shoulda initializer from spec/spec_helper.rb to test/test_helper.rb
I'm writing tests on Rspec for my models in Ruby on Rails application.
And I receive this error while starting 'rspec spec'
command:
/spec/models/client_spec.rb:4:in `<top (required)>': uninitialized constant Client (NameError)
I use Rails 4.0.0 and Ruby 2.0.0
Here is my client_spec.rb:
require 'spec_helper'
describe Client do
it 'is invalid without first_name', :focus => true do
client = Client.new
client.should_not be_valid
end
end
And Gemfile:
source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.0.0.rc1'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0.rc1'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'
# gem 'therubyracer', platforms: :ruby
# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes following links in your web application faster. Read more:
gem 'turbolinks'
gem 'jbuilder', '~> 1.0.1'
group :development do
gem 'rspec-rails'
end
group :doc do
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', require: false
end
group :test do
gem 'rspec-rails'
gem 'factory_girl_rails'
gem 'database_cleaner'
end
And at last client.rb (ROR Model and Class):
class Client < ActiveRecord::Base
has_many :cars
has_many :orders
has_one :client_status
has_one :discount_plan, through: :client_status
validates :email, format: { with: /^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})\z/, :message => "Only emails allowed", :multiline => true }
validates :email, presence: true, if: "phone.nil?"
#validates :phone, presence: true, if: "email.nil?"
validates :last_name, :first_name, presence: true
validates :last_name, :first_name, length: {
minimum: 2,
maximum: 500,
wrong_length: "Invalid length",
too_long: "%{count} characters is the maximum allowed",
too_short: "must have at least %{count} characters"
}
end
If it'd be useful my spec_helper.rb file:
# This file was generated by the `rspec --init` command. Conventionally, all
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
# Require this file using `require "spec_helper"` to ensure that it is only
# loaded once.
#
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
RSpec.configure do |config|
config.treat_symbols_as_metadata_keys_with_true_values = true
config.run_all_when_everything_filtered = true
config.filter_run :focus
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = 'random'
#config.use_transactional_fixtures = false
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
end
In rails 4.x and later (rspec-rails 3.1.0 and later) add this to the top of each of your spec files:
require "rails_helper" # this
not
require "spec_helper" # not this
Your spec_helper file is missing some important commands. Specifically, it's not including config/environment and initializing rspec-rails.
You can add the following lines to the start of your spec/spec_helper.rb file
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
or you can just run
rails generate rspec:install
and overwrite your spec_helper with one generated for use with rspec-rails.
You might also like to add --require rails_helper in your .rspec file so that it looks like this.
--color
--require spec_helper
--require rails_helper
You won't need to require rails_helper in all your specs, after this.
I'm using Rails 5.0.0.1.
Here's how I resolved this concern.
On your Gemfile, please add -> gem 'rspec-rails', ">= 2.0.0.beta"
Like so,
group :development, :test do
gem 'rspec-rails', ">= 2.0.0.beta"
end
Reason: if the rspec-rails is not added and when you execute the rspec command, it will generate this error -> "cannot load such file -- rails_helper"
Now, execute this command on the terminal.
bundle install
Once bundle command went good, execute the rails generate. Like so,
rails generate rspec:install
Reason: this command will create a new .rspec(hit overwrite when prompted), spec/rails_helper.rb and spec/spec_helper.rb
Now, at this point, rspec should pretty much run properly.
However, if you encounter an error where in the model is not found e.g. cannot load such file -- idea, try adding this on top of your spec/spec_helper.rb
require 'rubygems'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
Reason: seems that spec_helper is not loading the Rails environment. We're requiring it.
Hope this helps!
If other answers under this question don't work, try:
Check if there is any typo in the file name or class name (they should match)
Other wise,
Check your config/environment/test.rb file,
see if there is config.eager_load = false, set it to true.
You should check in the written order since you don't want to solve the issue with the typo laying there.
None of the answers above quite hit the nail on the head for me, or weren't quite explicit enough with where lines of code needed to be placed. I'm using rails 6.0.2 and rspec-rails 4.1.0 and found two options that solved the issue.
Add the line require 'rails_helper' to the top of each spec file that you need to run.
Add the line require 'rails_helper' to the top of the spec/spec_helper.rb file to make the rails helper file available in all tests.
Things have moved a bit since this thread has been created, I have experienced the uninitialized constant ClassName (NameError) error too using Ruby 2.1, Rails 4.2, rspec-rails 3.3.
I have solved my problems reading the rspec-rails gem documentation :
https://github.com/rspec/rspec-rails#model-specs
where it confirms what Swards says about requiring "rails_helper" not "spec_helper" anymore.
Also my model specification looks more like the one from the gem docs
RSpec.describe Url, :type => :model do
it 'is invalid without first_name', :focus => true do
client = Client.new
client.should_not be_valid
end
end
Factories folder define in your app
FactoryBot.define do
factory :user_params , :class => 'User' do
username 'Alagesan'
password '$1234#..'
end
end
Your Controller RSpec file:
it 'valid params' do
post :register, params: {:user => user_params }
end
UPDATE 2: require {path_to_spec_helper} solves the setup undefined issue, but now all of the static variables are suddenly undefined, and All FactoryGirl-made objects don't pass validation (even though inspecting shows that the object should pass validation). And Changing FactoryGirl to save_with_validation(false) just makes the object nil in my tests, breaking everything.
UPDATE:
I threw this into my code:
context "some context" do
ap self.respond_to?(:setup)
setup do
raise "stop"
And the respond_to line printed true, but then proceeded to throw the method_missing error below. So, I guess it's just undefined within context? It didn't used to be that way.
Original Post:
For some reason, unknown to me, it seems that context / should / setup are undefined in my tests. I'd change all the setup's to before(:each)'s and then there would be a problem with should or context. When I change all of the rspec / shoulda matchers to the old-skool style of describe - before(:each) - it{}, my tests will run, but won't actually get executed. (the progress in the console shows no tests being run (no dots)).
So, I guess, how do I verify my test environment is set up properly?
Here is my configuration
gem file:
# can't be in test group because it's required in the rake file
gem "single_test"# because running all the tests all the time takes too long
group :test do
# helper gems
gem "rspec-rails", "1.3.4"
gem "rspec", "1.3.2"
gem "shoulda"
gem "database_cleaner"
gem "crack" #for XML / JSON conversion
gem "mocha" #required for .requires and .stubs
gem "factory_girl", :require => false
# view and functional
gem "capybara", "1.1.1"
gem "cucumber", "1.1.0"
gem "cucumber-rails", "0.3.2"
gem "culerity"
gem "launchy"
gem "hpricot"
gem "gherkin"
gem "rack"
gem "webrat"
# tools
gem "json"
gem "curb"
end
Required things in test hepler:
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
require "bundler/setup"
Bundler.require(:test)
require 'test_help'
require 'spec'
require 'spec/expectations'
require 'factory_girl'
binary info:
ruby 1.8.7
rvm 1.7.2
gem 1.8.21
bundle 1.1.4
rake 0.9.2.2
rails 2.3.14
And my error:
`method_missing': undefined method `setup' for Spec::Example::ExampleGroup::Subclass_1:Class (NoMethodError)
stack trace:
from test/unit/my_test.rb:257
from /Users/me/.rvm/gems/ruby-1.8.7-p352/gems/rspec-1.3.2/lib/spec/example/example_group_methods.rb:188:in `module_eval'
from /Users/me/.rvm/gems/ruby-1.8.7-p352/gems/rspec-1.3.2/lib/spec/example/example_group_methods.rb:188:in `subclass'
from /Users/me/.rvm/gems/ruby-1.8.7-p352/gems/rspec-1.3.2/lib/spec/example/example_group_methods.rb:55:in `describe'
from /Users/me/.rvm/gems/ruby-1.8.7-p352/gems/rspec-1.3.2/lib/spec/example/example_group_factory.rb:31:in `create_example_group'
code around line 257 of the last code bit on the stack:
context "some context" do
setup do
...
If you didn't, first you have to generate your spec/spec_helper.rb and spec/rails_helper.rb files. you can do this with the following command:
rails generate rspec:install.
Once the files are created, make sure rails_helper.rb requires spec_helper.rb, otherwise it will not work and require "rails_helper" on top of your spec files.
You can check more detailed configuration of rails_helper.rb and spec_helper.rb here: https://kolosek.com/rails-rspec-setup
We are extracting a few models into a gem so it can be shared among a couple different services and we aren't able to get rspec running in the gem. When we require the gemname in the spec_helper it errors saying:
uninitialized constant Object::ActiveRecord
Some of the file contents are below. Any ideas?
Right now the spec helper is as follows:
require 'rubygems'
require 'bundler/setup'
RSpec.configure do |config|
Bundler.require(:default,"test")
require 'tup-user' # and any other gems you need
end
Our Gemfile is:
source :rubygems
# Specify your gem's dependencies in tup-user.gemspec
gemspec
gem 'rspec-rails'
gem 'aasm'
gem 'authlogic'
gem 'rails'
The line the error is being thrown on is the first of the class:
class User < ActiveRecord::Base
(See comments to question) After getting some good advice on the ruby-talk mailing list, I now require any libraries a file needs within the file itself.
in my environments/test.rb:
config.gem "rspec"
config.gem "rspec-rails"
relevant part of my gemfile:
group :test do
...
gem "rspec", "1.3.2"
gem "rspec-rails", "1.3.2"
in test_helper.rb
require 'test_help'
require "bundler/setup"
Bundler.require(:test)
require 'factory_girl'
require 'shoulda'
require "shoulda-matchers"
require 'spec'
require 'spec/matchers'
I recently moved all my gems to a gemfile, instead of having everything in config.gem's
in my env/test.rb file, I have to use the two config.gem's or my tests don't run at all.
I've read that including spec_helper will help.... but my tests aren't in the spec folder... they are in the test folder... when I include spec/spec_helper.rb, all of my tests get WARNING: already defined.
EDIT: I found this link: https://github.com/rspec/rspec-rails/issues/93
which told me to do
include RSpec::Matchers
and I got a differente error with this one:
/Users/lprestonsegoiii/.rvm/rubies/ruby-1.8.7-p352/lib/ruby/1.8/optparse.rb:314:in `initialize': unhandled exception
EDIT2:
I've discovered through using IRB, that the minimum to use the matchers are:
require "spec/spec_helper"
include RSpec::Matchers
But I still have the duplicate definition issue. hmm.