Search code examples
ruby-on-railsrspecdatabase-cleaner

Rspec and database_cleaner only remove the data added by the tests


I want to be able to always have access to my seed data on my test database. I understand database_cleaner will remove everything if it's set up that way.

I try to remove everything and then reloading the seed, but when I try to use js: true on a test, the seed never gets loaded so i get errors saying data does not exist.

My spec_helper.rb

RSpec.configure do |config|
  # before the entire test suite runs, clear the test database out completely
  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end
  # sets the default database cleaning strategy to be transactions (very fast)
  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end
  # For these types of tests, transactions won’t work. We must use truncation
  config.before(:each, js: true) do
    DatabaseCleaner.strategy = :truncation
  end
  # hook up database_cleaner around the beginning and end of each test, telling it to execute whatever cleanup strategy we selected beforehand.
  config.before(:each) do
    DatabaseCleaner.start
  end
  config.after(:each) do
    DatabaseCleaner.clean
  # reload the seed so we have data to play with
  end
  config.before :all do
    Rails.application.load_seed
  end
end

When in my view_spec I have something like this

require 'spec_helper'
describe 'my/path', type: :view do
  before do
    @user = create(:user)
    @user.permissions << Permission.first
    login_as(@user)
    visit my_path
  end
  it 'should have a valid user, just for kicks' do
    @user.should be_valid
  end
  it 'should be in the path i said' do
    expect(current_path).to eq(my_path)
  end
  describe 'click submit button', js: true do
    it 'should take me to a different path' do
      click_link('button_1')
      expect(current_path).to eq(my_new_path)
    end
  end
end

The first two test will run and be ok with creating that user, but as soon as it hits that last test with js: true, it no longer has Permission in the database.

Is there a way to tell database_cleaner to only delete the data added by rspec? and not the seed? Or maybe even tell it to not delete certain tables?

Any help would be appreciated.


Solution

  • Try to use :truncation for all tests with:

    DatabaseCleaner.strategy = :truncation
    
    RSpec.configure do |config|
      config.before(:each) do
        DatabaseCleaner.clean
        Rails.application.load_seed
      end
    end
    

    There also may be an issue with your seeds and not with DatabaseCleaner. You should debug your database state right in the failing test using puts statements or debugger (e.g. pry-byebug).