Leo Jiang
Leo Jiang

Reputation: 26075

Records created in Rspec aren't available in new threads?

In Rspec, I'm creating records, e.g. let!(:user) { create(:user) }.

I can access the new user in Rspec and in the main thread of the subject. Both of these return the user:

puts User.all.to_a
puts ActiveRecord::Base.connection.exec_query('select * from users')

However, I can now longer access the user in a new thread:

Thread.new do
    puts User.all.to_a
    puts ActiveRecord::Base.connection.exec_query('select * from users')
end

How do I fix this? Is this just an Rspec issue? I don't think I can reproduce it in Rails console.

Upvotes: 2

Views: 1088

Answers (1)

spickermann
spickermann

Reputation: 106792

You have probably configured RSpec to run its test within a database transaction

Quote from the RSpec Docs: >

When you run rails generate rspec:install, the spec/rails_helper.rb file includes the following configuration:

RSpec.configure do |config|
  config.use_transactional_fixtures = true
end

The name of this setting is a bit misleading. What it really means in Rails is "run every test method within a transaction." In the context of rspec-rails, it means "run every example within a transaction."

The idea is to start each example with a clean database, create whatever data is necessary for that example, and then remove that data by simply rolling back the transaction at the end of the example.

You might want to disable this configuration when your application tests have the requirement to support multiple threads at the same time.

But that means that your test database will not be cleared from test data automatically anymore when a test is done. Instead, you will need to delete the test data manually or use another gem (like database_cleaner) to reset the database after running tests.

Upvotes: 3

Related Questions