Rspec: Transactional fixtures do not work after upgrading to rails 4

activerecord, rspec, ruby-on-rails

Solution

I had exactly the same issue (with rspec-rails 3.1) on rails 4.1. Didn't have auto-run running, although I did have spring, which may be the culprit. However, I decided to try an alternative, which worked nicely: database cleaner, which does a similar job: https://github.com/DatabaseCleaner/database_cleaner

So add to Gemfile:

group :test do
...
  gem 'database_cleaner'
...
end

Then change to rails helper:

  #Database cleaning
  config.use_transactional_fixtures = false #IMPORTANT, make sure that rails doesn't try and clean it
  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction #usually use transaction as the strategy - this is what transaction_fixtures does
    DatabaseCleaner.clean_with(:truncation) # I like to ensure my database is in clean state to start with so I truncate at the start of the suite - this is optional.
  end 

  config.around(:each) do |example|
    DatabaseCleaner.cleaning do
      example.run
    end 
  end 

Problem

I have the following line set in spec_helper.rb ``` config.use_transactional_fixtures = true ``` This means that every test should cleanup after itself. Any db update made by one test should not be around for the next test. I have two tests in one of my spec files. ``` it 'should update the DB' do Setting.put('abcd', 'efgh') end it 'should not find the DB update' do Setting.get('abcd').should be_nil end ``` The above two test used to work with Rails 3.2.14 However after upgrading to Rails 4, the second test fails with the following error, ``` ------ expected: nil got: "efgh" ----- ``` I have about a 100 tests failing in the suite because of this issue. The only related documentation I can find for Rails 4 upgrade was something quite vague: "Rails 4.0 has deprecated ActiveRecord::Fixtures in favor of ActiveRecord::FixtureSet." I am not sure if/how this is relevant. I would ideally like to have a global setting (config.use_transactional_fixtures = true), and not have to change the logic of the tests (or add extra before(:each)/after(:each) modules just to get existing tests to pass. Please help!

Original source