Rspec doesn't see my model Class. uninitialized constant error - ruby-on-rails

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

Related

RSPEC Can't find Controllers Uninitialized Constants

I recently started adding tests to my app and I am facing some issues regarding the controllers tests. When I try to run any controller test I get this error:
-> bundle exec rspec -c -b spec/controllers/culture_test_controller_spec.rb
ActiveRecord::SchemaMigration Load (0.6ms) SELECT "schema_migrations".* FROM "schema_migrations"
/home/rodras/Github/talentank/spec/controllers/culture_test_controller_spec.rb:4:in `<top (required)>': uninitialized constant CultureTestController (NameError)
The strange thing is that all the models tests seem to be working fine, that is why I assume that the issue is not in rails_helper.rb nor in spec_helper.rb
I have already check questions that seemed to have the same problem such as: RSpec Cannot find my Controllers Uninitialized Constant but the solutions offered there didn't help me
These are my files. If there is any other file that you need in order solve the question please let me know, and I will update the question.
rails_helper.rb
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'shoulda/matchers'
# Add additional requires below this line. Rails is not loaded until this point!
# 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 before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.include FactoryGirl::Syntax::Methods
# 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!
end
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end
spec_helper.rb
require File.expand_path("../../config/environment", __FILE__)
# This file was generated by the `rails generate rspec:install` command. Conventionally, all
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
# The generated `.rspec` file contains `--require spec_helper` which will cause this
# file to always be loaded, without a need to explicitly require it in any files.
#
# Given that it is always loaded, you are encouraged to keep this file as
# light-weight as possible. Requiring heavyweight dependencies from this file
# will add to the boot time of your test suite on EVERY test run, even for an
# individual file that may not need all of that loaded. Instead, consider making
# a separate helper file that requires the additional dependencies and performs
# the additional setup, and require it from the spec files that actually need it.
#
# The `.rspec` file also contains a few flags that are not defaults but that
# users commonly want.
#
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
RSpec.configure do |config|
# rspec-expectations config goes here. You can use an alternate
# assertion/expectation library such as wrong or the stdlib/minitest
# assertions if you prefer.
config.expect_with :rspec do |expectations|
# This option will default to `true` in RSpec 4. It makes the `description`
# and `failure_message` of custom matchers include text for helper methods
# defined using `chain`, e.g.:
# be_bigger_than(2).and_smaller_than(4).description
# # => "be bigger than 2 and smaller than 4"
# ...rather than:
# # => "be bigger than 2"
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
# rspec-mocks config goes here. You can use an alternate test double
# library (such as bogus or mocha) by changing the `mock_with` option here.
config.mock_with :rspec do |mocks|
# Prevents you from mocking or stubbing a method that does not exist on
# a real object. This is generally recommended, and will default to
# `true` in RSpec 4.
mocks.verify_partial_doubles = true
end
# For using same seed as development environment
config.before(:all) do
#load Rails.root + "db/seeds.rb"
Rails.application.load_seed # loading seeds
end
# The settings below are suggested to provide a good initial experience
# with RSpec, but feel free to customize to your heart's content.
begin
# These two settings work together to allow you to limit a spec run
# to individual examples or groups you care about by tagging them with
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
# get run.
config.filter_run :focus
config.run_all_when_everything_filtered = true
# Limits the available syntax to the non-monkey patched syntax that is recommended.
# For more details, see:
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
config.disable_monkey_patching!
# Many RSpec users commonly either run the entire suite or an individual
# file, and it's useful to allow more verbose output when running an
# individual spec file.
if config.files_to_run.one?
# Use the documentation formatter for detailed output,
# unless a formatter has already been configured
# (e.g. via a command-line flag).
config.default_formatter = 'doc'
end
# Print the 10 slowest examples and example groups at the
# end of the spec run, to help surface which specs are running
# particularly slow.
config.profile_examples = 10
# 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
# Seed global randomization in this process using the `--seed` CLI option.
# Setting this allows you to use `--seed` to deterministically reproduce
# test failures related to randomization by passing the same `--seed` value
# as the one that triggered the failure.
Kernel.srand config.seed
end
end
One of my controller tests: spec/controllers/culture_test_controller_spec.rb
require 'rails_helper'
require 'rspec/its'
RSpec.describe CultureTestController, type: :controller do
describe "GET #index" do
it "returns a specific culture test" do
culture_test = FactoryGirl(:culture_test)
get :index
expect(response).to render_text(:culture_test)
end
it "returns all the culture tests" do
culture_test = FactoryGirl(:invalid_culture_test)
get :index
expect(response).to render_text(CultureTest.all)
end
end
end
The respective controller: culture_test_controller.rb
module Api
class CultureTestController < ApplicationController
before_action :find_culture_test, only: [:show, :edit, :update, :registration, :results]
def index
if(params[:company_id] != nil && params[:title] != nil)
respond_to do |format|
format.json{
render text: CultureTest.where(:company_id => params[:company_id]).where(:title => params[:title]).first.to_json
}
end
else
respond_to do |format|
format.json{
render text: CultureTest.all.to_json
}
end
end
end
Gemfile:
source 'https://rubygems.org'
ruby "2.1.3"
### APP DEFAULT GEMS
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.0'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.1.0'
gem 'sprockets', '2.12.3'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
# Removed so that we can use AngularJS
# gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.0'
gem 'responders'
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', '~> 0.4.0', group: :doc
# Bower package manager
gem 'bower-rails'
gem 'rails-html-sanitizer'
### FRONT-END STUFF
# Use jquery as the JavaScript library
gem 'jquery-rails'
# Using the jQuery UI framework
gem 'jquery-ui-rails'
# And some nice jQuery gems
gem 'jquery-validation-rails'
gem 'jquerymobile-rails'
# Talentank's front-end devs prefer haml over erb
gem 'haml'
# Zurb's Foundation as HTML+CSS framework
gem 'foundation-rails'
# We want to use the Foundation icons too
gem 'foundation-icons-sass-rails'
# Font Awesome: awesome icons
gem "font-awesome-rails"
# Animate.css as a Rails gem (simple CSS animations)
gem 'animate-rails'
# EU cookies law
gem 'cookies_eu'
# Angular templates for simple Angular templates as asset referencing
gem 'angular-rails-templates'
# Gem for authenticate with protection token
gem 'angular_rails_csrf'
### BACK-END STUFF
# let's use PostgreSQL. Yay!
gem 'pg'
# let's get rid of that webrick crap
gem "puma"
# Devise as user authenticator and session management
gem 'devise'
# gem 'devise_token_auth' # Token based authentication for Rails JSON APIs
# gem 'omniauth' # required for devise_token_auth
# Paperclip allows us to attach files (such as logos in company profiles)
gem 'paperclip'
# i18n for internationalization (app translation)
gem 'i18n'
gem 'i18n-js'
# Globalize is used to translate the database
gem 'globalize'
# Simple_form for, guess what, simple forms
gem 'simple_form'
# Allows country selection in simple form
gem 'country_select'
# mail_form for simple, yet nice contact forms
gem 'mail_form'
### DEVOPS STUFF (anything related to the logistics of deploying the app)
# rails_12factor has to do with Heroku and devops
gem 'rails_12factor'
# yaml_db: db migrations to heroku
gem 'yaml_db'
# Backend for working in background
gem 'delayed_job_active_record'
# To run jobs
gem 'daemons'
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug'
# Access an IRB console on exception pages or by using <%= console %> in views
gem 'web-console', '~> 2.0'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'rspec-rails'
gem 'rspec-its'
gem 'shoulda-matchers', require: false# Helps with the test models with belongs_to and has_many
# Fuubar formats RSpec output in a nice way
# gem 'fuubar'
#FactoryGirl is a library for setting up Ruby objects as test data.
gem 'factory_girl_rails'
#Faker for creating fake dummy fields
gem 'faker'
gem 'mailcatcher'
end
I think the problem might be here
spec/controllers/culture_test_controller_spec.rb
RSpec.describe CultureTestController, type: :controller do
It should be:
RSpec.describe Api::CultureTestController, type: :controller do

uninitialized constant (NameError)

I have seen few similar questions here on SO but none of the given solutions work. I have installed rspec/factorygirl as usual and i'm facing some problems i can't understand. It seems that rspec can't see my models.
Gefile
group :development, :test do
gem 'rspec-rails', '~> 3.0'
gem 'factory_girl_rails'
gem 'database_cleaner'
gem 'faker'
end
group :test do
gem 'guard-rspec'
gem 'capybara'
end
I have run rails generate rspec:install to generate the spec/ dir file structure (so my spec_helper and rails_helper files contains the proper lines with environment require etc.)
spec/models/list_spec.rb
require 'spec_helper'
describe List do
before(:each) do
#list = FactoryGirl.build(:list)
end
it 'is invalid without name' do
#list.title = nil
expect(#list).to_not be_valid
end
end
spec_helper.rb
https://gist.github.com/mbajur/68e96ab77f43d50a73cf
rails_helper.rb
https://gist.github.com/mbajur/677c9936347be8b18c7d
list_factory.rb
https://gist.github.com/mbajur/49668f280891fa80f288
And when i run rspec, it gives me uninitialized constant List (NameError) on line 3 of list_spec.rb file.
Change describe List do ... to describe 'List' do ... and be sure what you require all needed lib in helper file and leave one _helper.rb.
Problem was caused by the fact that i was requireing spec_helper in all my specs while i should require rails_helper.
So, each spec file should start with the following line:
require 'rails_helper`

How can I clean my database between erroneous rspec specs?

I have added the database_cleaner gem to my rails application in order to clean my database between specs. Here's my current configuration for database_cleaner, located in spec/spec_helper.rb:
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
DatabaseCleaner.start
DatabaseCleaner.clean
end
config.before(:each) do
DatabaseCleaner.clean
end
config.after(:each) do
DatabaseCleaner.clean
end
config.after(:suite) do
DatabaseCleaner.clean
end
Now, this configuration works fine, so long as every last spec that is run either passes or fails.
However, in the event of an error (rspec doesn't give you a nice little E like minitest, it throws this sort of thing:
09:17:32 - INFO - Running: spec
/usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/validations.rb:57:in `save!': Validation failed: Email has already been taken (ActiveRecord::RecordInvalid)
), the database isn't cleaned! Residual data from the spec just before the error stays in the database. I suppose this is because database_cleaner doesn't regard the erroneous spec as finishing and so doesn't clean the database.
Now, this doesn't really cause any harm until you run your specs again. The residual data then causes an error analogous to this:
09:17:32 - INFO - Running: spec
/usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/validations.rb:57:in `save!': Validation failed: Email has already been taken (ActiveRecord::RecordInvalid)
Getting around this error is simple enough; running rails_env=test rake db:reset or firing up your database shell and emptying the relevant tables with sql statements will clear this data and allow the specs to be run without a hitch.
However, this is getting annoying. One wrong character in any of my specs (anything to make it erroneous rather than a failure) causes my whole testing workflow to jam up, almost like the firing mechanism of an automatic weapon!
What are your suggestions regarding database_cleaner? Do you have any example configurations that allow for the database to be cleaned, even in the event of an erroneous test?
I'm using guard to run my rspecs that are further augmented with factory-girl:
Gemfile:
source 'https://rubygems.org'
group :development do
gem 'capistrano'
gem 'rb-fsevent'
gem 'debugger'
end
group :development, :test do
gem 'rspec-rails', '~> 2.14.0'
gem 'sqlite3'
gem 'guard-rspec'
gem 'guard-livereload', require: false
gem 'guard-shell'
gem 'webrick', '~> 1.3.1'
end
group :test do
gem 'factory_girl_rails'
gem 'capybara', '~> 2.2.0'
gem 'selenium-webdriver'
# capybara-webkit gem requires an application called 'libqtwebkit-dev' to build. To install 'libqtwebkit-dev' in Ubuntu, run
# sudo apt-get install libqtwebkit-dev
# gem 'capybara-webkit'
gem 'rb-readline'
gem 'launchy'
gem 'database_cleaner'
end
group :production do
gem 'pg'
# gem 'puma'
end
# rails version
gem 'rails', '4.0.1'
# standard library
gem 'sass-rails', '~> 4.0.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.0.0'
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 1.2'
group :doc do
gem 'sdoc', require: false
end
# custom
gem 'activeadmin', github: 'gregbell/active_admin'
gem 'devise'
gem 'simple_form'
spec/spec_helper:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/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 }
# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
RSpec.configure do |config|
config.include Capybara::DSL
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
DatabaseCleaner.start
DatabaseCleaner.clean
end
config.before(:each) do
DatabaseCleaner.clean
end
config.after(:each) do
DatabaseCleaner.clean
end
config.after(:suite) do
DatabaseCleaner.clean
end
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# config.include RSpec::Rails::RequestExampleGroup, type: :feature
# 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
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
# 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"
end
You want to change this
config.after(:suite) do
DatabaseCleaner.clean
end
To this:
config.after(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
Otherwise, it will simply roll back the transaction, which will leave any data that existed before the transaction was started.
add a file:
# RSpec
# spec/support/database_cleaner.rb
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
end
and uncomment
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
in spec/rails_heper.rb
This works for me:
DatabaseCleaner.strategy = :truncation
...
before(:each) do
DatabaseCleaner.clean
end
Please show the spec(s).
You need to be sure that your setup/teardown is done in before/after/its, etc. statements.
If you have setup and variable assignment outside of the above and just 'in the test itself' then the test will bomb out as you are experiencing. If done in setup, this problem can be avoided.
You should not need to be trying to jigger with the internals the way you are. As with many thing in Ror land, if you're doing this, chances are you may be 'going' off the rails with your code. Rails is intended to be a framework that does all the tedium for you, you just have to stay 'on the rails'.

Issue with Paperclip and Rspec: undefined method `has_attached_file'

I'm adding Rspec tests to a project that didn't have rspec before, or automated tests at all. It is running on a Windows 7 box. When I run rspec, it shows the error:
undefined method `has_attached_file'
The main issue is that I'm writing just a simple test for a model that is not using Paperclip at all. Paperclip is used on another model.
I've researched extensively, trying to include the gem in test environment but nothing seems to solve the issue.
Is there a way of skipping or forcing the inclussion of paperclip when I run the rspec tests?
My gemfile has, among other things, the following:
source 'http://rubygems.org'
ruby "1.9.2"
gem 'rails', '3.0.20'
...
gem "paperclip", :git => 'git://github.com/thoughtbot/paperclip.git'
gem 'aws-s3'
gem 'aws-sdk'
group :test, :development do
gem 'rspec-rails', '~> 2.14.0'
end
group :test do
gem 'sqlite3'
gem 'capybara', '2.0'
gem 'selenium-webdriver'
gem 'shoulda-matchers'
gem 'database_cleaner'
gem 'launchy', '2.2.0'
gem 'factory_girl_rails'
end
I run the rspec command:
bundle exec rake spec
I get the following error:
C:/Users/MAC/.pik/rubies/Ruby-192-p290/bin/ruby.exe -S rspec ./spec/models/filter_category_spec.rb ./spec/models/filter_spec.rb
C:/Users/MAC/.pik/rubies/Ruby-192-p290/lib/ruby/gems/1.9.1/gems/attr_encrypted-1.2.1/lib/attr_encrypted.rb:241:in `method_missing': undefined method `has_a
ttached_file' for #<Class:0x5278770> (NoMethodError)
from C:/Users/MAC/.pik/rubies/Ruby-192-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.0.20/lib/active_record/base.rb:1018:in `method_missing'
from C:/Users/MAC/.pik/rubies/Ruby-192-p290/lib/ruby/gems/1.9.1/gems/attr_encrypted-1.2.1/lib/attr_encrypted/adapters/active_record.rb:50:in `metho
d_missing_with_attr_encrypted'
....
from C:/Users/MAC/.pik/rubies/Ruby-192-p290/lib/ruby/gems/1.9.1/gems/railties-3.0.20/lib/rails/application.rb:77:in `method_missing'
from C:/Avity/DS Candidates Tracking System/ds-cts/config/environment.rb:5:in `<top (required)>'
from C:/Avity/DS Candidates Tracking System/ds-cts/spec/spec_helper.rb:3:in `require'
from C:/Avity/DS Candidates Tracking System/ds-cts/spec/spec_helper.rb:3:in `<top (required)>'
from C:/Avity/DS Candidates Tracking System/ds-cts/spec/models/filter_category_spec.rb:1:in `require'
My spec_helper file is:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/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}
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = false
config.infer_base_class_for_anonymous_controllers = false
config.order = "random"
#Database cleaner
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
#Use chrome driver
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
Capybara.current_driver = :selenium_chrome
end
Any ideas of what should I do to make this work properly?
EDIT It seems the issue comes before loading spec_helper.rb
If I make changes on this file, like adding errors on purpose, nothing happens and the issue above keeps happening.
The only way I have to run the tests is by commenting the has_attached_file line on my model and adding the group option to the paperclip gem on my Gemfile, to avoid having it on test environment:
gem "paperclip", :git => 'git://github.com/thoughtbot/paperclip.git', :group=>[:development,:production]
Not sure how to solve this without skipping Paperclip from test env.
The problem seems to me to be with shoulda-matchers and paperclip
Add to your spec_helper.rb file
require "paperclip/matchers"
below where you are
require "capybara/rspec"
And add
config.include Paperclip::Shoulda::Matchers
below
RSpec.configure do |config|
Check out the shoulda-matchers documentation for paperclip
Hope this helps
I ran into this issue when trying to use Paperclip in a gem that has ActiveRecord, but not Rails. I was able to fix this for tests by adding a spec/support/paperclip.rb file with the following:
require 'paperclip/railtie'
RSpec.configure do |config|
# Bind paperclip to enable ActiveRecord #has_attached_file method
Paperclip::Railtie.insert
end
As also suggested, this is a good place to add config.include Paperclip::Shoulda::Matchers.
But I'm using Rails 4.2 and Rspec 3, so I think the order of things loaded is much different than yours.

Why cant I get selenium to kick in with capybara

Im trying to test a user clicking on a button which makes an ajax call. When i click it manuallly in my browser it behaves as expected i.e. default behaviour of the button is ignored and instead it gets the results via ajax which are then added to the page.
But when i run my tests using capybara, after clicking on the button it redirects to the buttons action. It seems selenium isnt kicking in. I cant figure out why.
Is it my config? Since it works in development mode Im assuming this isnt due to my jquery code so for brevity not displaying that.
Gemfile
source 'http://rubygems.org'
gem 'rails', '3.1.0.rc4'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
gem 'sqlite3'
gem 'omniauth', '~>0.2.0'
gem 'pusher'
gem 'youtube_it'
gem 'simple_form'
# Asset template engines
gem 'sass-rails', "~> 3.1.0.rc"
gem 'coffee-script'
gem 'uglifier'
gem 'jquery-rails'
# Use unicorn as the web server
# gem 'unicorn'
# Deploy with Capistrano
# gem 'capistrano'
# To use debugger
# gem 'ruby-debug19', :require => 'ruby-debug'
group :test do
gem "shoulda"
gem "factory_girl_rails"
# Pretty printed test output
gem 'turn', :require => false
gem 'mocha'
end
group :development do
gem 'rails3-generators'
gem "autotest"
end
group :development, :test do
gem "capybara", :git => 'git://github.com/jnicklas/capybara.git'
gem "launchy"
gem "haml-rails"
gem "database_cleaner"
end
or my test_helper
ENV["RAILS_ENV"] = "test"
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require 'shoulda/rails'
require "capybara/rails"
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
#
# Note: You'll currently still have to declare fixtures explicitly in integration tests
# -- they do not yet inherit this setting
fixtures :all
OmniAuth.config.test_mode = true
# Add more helper methods to be used by all tests here...
def login_in(user)
#request.session[:user_id] = user.id
end
def should_redirect_unauthorized
assert_redirected_to root_path
assert_match /you need to login/i, flash[:alert]
end
end
module ActionController
class IntegrationTest
include Capybara::DSL
self.use_transactional_fixtures = false
setup do
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.start #workaround for capybara / selenium. See capybara docs
end
teardown do
DatabaseCleaner.clean #workaround for capybara / selenium. See capybara docs
end
#signup using twitter, facebook for authentication
def signup_using(provider)
OmniAuth.config.add_mock(provider.to_sym, {'uid' => "123456"})
visit '/'
page.click_link("#{provider}_auth")
assert_match /\/users\/\d+\/edit/, current_path
assert page.find("#flash").has_content?("Welcome to")
end
#login into existing account using twitter, facebook
def login_using(service)
OmniAuth.config.add_mock(service.provider.to_sym, {'uid' => service.uid})
visit '/'
page.click_link("#{service.provider}_auth")
assert page.find("#flash").has_content?("Welcome back")
assert_equal rooms_path, current_path
end
def login_and_visit_room(service, room)
login_using(service)
visit_room(room)
end
def visit_room(room)
visit room_path(room)
assert_equal room_path(#room.id), current_path
end
end
end
or the setup blocks in my integration test
require 'test_helper'
class PlaylistStoriesTestTest < ActionDispatch::IntegrationTest
fixtures :all
setup do
Capybara.current_driver = :selenium
#user = Factory(:user)
#service = #user.services.create(:provider => "twitter", :uid => "123456")
#room = Factory(:room)
end
....
teardown do
Capybara.use_default_driver
DatabaseCleaner.clean #workaround for capybara / selenium. See capybara docs
end
end
With Capybara, you should not get confused with the difference between a link (even if it looks like a button) and a button (like "submit"). You did not provide the view file contents, but I guess, you are using a button, not a link.
With capybara, you have to differentiate
visit '/'
click_button 'Login'
or
visit '/'
click_link 'Home'
See also the Capybara-Documentation at GitHub

Resources