How to configure database_cleaner with rails - ruby-on-rails

I have some services inside my app/services folder.Now I want to test these services, so I am using rspec and factorygirl. I am creating user with factoryGirl, but when i am running rspec it is showing me following error
Failure/Error: #user ||= FactoryGirl.create(:user)
ActiveRecord::RecordInvalid:
Validation failed: Email has already been taken
I am using database_cleaner gem to clean the database after each test.
Below is my config file
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'
require 'factory_girl_rails'
require 'database_cleaner
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.include Devise::TestHelpers, type: :controller
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
config.infer_spec_type_from_file_location!
config.filter_rails_from_backtrace!
end
I don't know where i am going wrong.

You need to specify the strategy to use between each specs (transaction is a safe choice here):
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end

Related

How to populate and clean a database in ruby on rails with a rake task and database cleaner gem?

I have two rake tasks in one file. seed and populate.
seed is creating a necessary data, and populate is populating sample data for my tests.
In my tests I am manipulating a database(adding the new entry, removing it and etc.). I am using Database cleaner gem to reseting the database However when I reset the database I need the populate data for the next test. I have the following setting but it is not working the database is still empty and the populate data is not there .
this is the spec/support/database_cleaner.rb
require 'rake'
load File.expand_path("../../../lib/tasks/my_tasks.rake", __FILE__)
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, :js => true) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
Rake::Task.define_task(:environment)
Rake::Task['db:seed'].invoke
Rake::Task['db:populate'].invoke
end
config.after(:each) do
DatabaseCleaner.clean
end
end
spec/rails_helper.rb
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV['RAILS_ENV'] ||= 'test'
require 'rake'
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 'factory_girl_rails'
require 'rspec/rails'
require 'capybara/poltergeist'
# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!
Capybara.configure do |config|
config.default_wait_time = 20
end
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.infer_spec_type_from_file_location!
end
I found a way around it but this is not perfect and I am still looking for the solution of this so please post an answer if you find it. I am not going to select this as the correct answer.
You need to place a content spec/support/database_cleaner.rb file into the spec/spec_helper.rb file.
RSpec.configure do |config|
.
.
.
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, :js => true) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
Rake::Task.define_task(:environment)
Rake::Task['db:seed'].invoke
Rake::Task['db:populate'].invoke
end
config.after(:each) do
# DatabaseCleaner.clean
end
config.infer_spec_type_from_file_location!
end
Important: You need to comment or delete the: DatabaseCleaner.clean

Issue on integrating Database cleaner gem in Ruby Rspec automation

I am getting the following error on executing the code.
No known ORM was detected! Is ActiveRecord, DataMapper, Sequel, MongoMapper, Mongoid, Moped, or CouchPotato, Redis or Ohm loaded? (DatabaseCleaner::NoORMDetected)
Can anyone pls suggest a solution for this.
spec_helper.rb:
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/rspec'
require 'database_cleaner'
DatabaseCleaner.strategy = :truncation
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/database_cleaner.rb")].each {|f| require f}
RSpec.configure do |config|
config.mock_with :mocha
config.before(:each) do
DatabaseCleaner.clean
#Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop) # transactional fixtures hack for mongo
end
config.expect_with :rspec do |c|
c.syntax = [:should, :expect]
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.color = true
config.use_transactional_fixtures = false
end
Hope this helps. Here is how I have my (working) database cleaner configured:
I have no database_cleaner.rb. I configure everything in rails_helper.rb. This shouldn't matter, but you may want to try below code and see if it works before splitting it out.
Notice that I have DatabaseCleaner.strategy = :truncation in a before block
Here is the relevant part of my rails_helper.rb
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.clean_with :truncation
end
config.before(:each) do |example|
if example.metadata[:js]
DatabaseCleaner.strategy = :truncation
else
DatabaseCleaner.strategy = :transaction
end
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
Add the following to your RSpec.configure block:
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
Also, to specify particular ORM, you can do this:
#How to specify particular orms
DatabaseCleaner[:active_record].strategy = :transaction
DatabaseCleaner[:mongo_mapper].strategy = :truncation
See this for more information.

`autodetect': No known ORM was detected

Unable to clean data using database_cleaner.rb; throwing the following issue on running tests.
/Users/prashanth_sams/.rvm/gems/ruby-2.0.0-p598/gems/database_cleaner-1.3.0/lib/database_cleaner/base.rb:147:in
`autodetect': No known ORM was detected! Is ActiveRecord, DataMapper,
Sequel, MongoMapper, Mongoid, Moped, or CouchPotato, Redis or Ohm
loaded? (DatabaseCleaner::NoORMDetected)
spec_helper.rb
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../config/environment", __FILE__)
require 'rspec/rails'
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.mock_with :rspec
config.use_transactional_fixtures = false
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.expect_with :rspec do |c|
c.syntax = [:should, :expect]
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.color = true
Selenium::Application.reload_routes!
end
database_cleaner.rb
require 'database_cleaner'
DatabaseCleaner.strategy = :truncation
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before :each do
DatabaseCleaner.start
end
config.after :each do
DatabaseCleaner.clean
end
end
I had same issue on controller_spec.
'autodetect': No known ORM was detected! Is ActiveRecord, DataMapper, Sequel, MongoMapper, Mongoid, Moped, or CouchPotato, Redis or Ohm loaded? (DatabaseCleaner::NoORMDetected)
I resolved by requiring rails_helper file on controller spec.
require 'rails_helper'
In rails_helper.rb require file 'database_cleaner'.
require 'database_cleaner'
I had this issue (on Rails 5.1) and the reason was that I had
config.before(:suite) do
DatabaseCleaner.clean_with :truncation
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
in my spec_helper.rb.
I put require 'database_cleaner in spec_helper.rb as well.
So eventually I moved both things to rails_helper.rb and that fixed the issue for me.
Use my setup, seems to work fine for RDBMS (checked on MySQL and Postgres), put it into your database_cleaner.rb:
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
# this may be needed for Capybara tests and for testing after_commit hooks
config.before(:each, strategy: :truncation) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
If you want to use truncation strategy, just use
describe 'something', strategy: :truncation or it 'something', strategy: truncation.

Problems with rspec 3, capybara and machinist 2

I have this feature test (Store model have a uniqueness validation):
feature "Index" do
before do
3.times { Store.make! }
end
scenario "User visit index" do
visit stores_path
within("table.table") do
Store.all.each do |store|
expect(page).to have_content(store.name)
end
end
end
end
When i run the test, randomly fails:
Failure/Error: 3.times { Store.make! }
ActiveRecord::RecordInvalid:
Validation failed: name has already been taken
My blueprint is (follow the machinist documentation to generate a unique record):
Store.blueprint do
name { "store #{sn}" }
end
I use DatabaseCleaner gem, then my config rails_spec:
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'shoulda/matchers'
require 'capybara/rails'
require 'capybara/rspec'
require 'pundit/rspec'
require 'database_cleaner'
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.mock_with :rspec
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = false
config.before(:each) do |example|
DatabaseCleaner.strategy = if example.metadata[:js]
:truncation
else
:transaction
end
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
DatabaseCleaner.logger = Rails.logger
config.infer_spec_type_from_file_location!
That errors are driving me crazy
Try to replace the following in your spec/spec_helper.rb:
config.before :suite do |example|
DatabaseCleaner.strategy = example.metadata[:js] ? :truncation : :transaction
end
config.before do
DatabaseCleaner.clean
end

SQLite3::SQLException when using database_cleaner with Rails / Spork / RSpec

When attempting to follow example on database_cleaner's GitHub page, I encountered the following error from RSpec:
ActiveRecord::StatementInvalid:
SQLite3::SQLException: cannot start a transaction within a transaction: begin transaction
The configuration used in spec_helper.rb is:
require 'spork'
require 'database_cleaner'
Spork.prefork do
# .. snip
RSpec.configure do |config|
# .. snip
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
end
Spork.each_run do
end
The accepted answer makes all tests slower (when it's not needed) by truncating after each one.
Just add
config.use_transactional_fixtures = false
when using database_cleaner.
If you have both config.use_transactional_fixtures = true and DatabaseCleaner.strategy = :transaction you're going to start a transaction inside another transaction and that's not allowed.
I found the solution to be changing the entire strategy to :truncation. Updated spec_helper:
require 'spork'
require 'database_cleaner'
Spork.prefork do
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
end
Spork.each_run do
end

Categories

Resources