I have a piece of code where I import a BankAccountTransaction
to a BankAccount
bank_account.with_lock do
transactions.each do |transaction|
import(bank_account, transaction)
end
end
it works fine but I need to write an RSpec case to it so I can be 100% sure I'm not importing transactions twice.
I wrote the following helper
module ConcurrencyHelper
def make_concurrent_calls(function, concurrent_calls: 2)
threads = Array.new(concurrent_calls) do
thread = Thread.new { function.call }
thread.abort_on_exception = true
thread
end
threads.each(&:join)
end
end
and I'm calling it on RSpec
context 'when importing the same transaction twice' do
subject(:concurrent_calls) { make_concurrent_calls(operation) }
let!(:operation) { -> { described_class.call(params) } }
let(:filename) { 'single-transaction-response.xml' }
it 'creates only one transaction' do
expect { concurrent_calls }.to change(BankaccountTransaction, :count).by(1)
end
end
but nothing happens, the test suit gets stuck at this point and no errors are thrown or anything like that.
I've put a debug point (byebug
) right after I instantiate the threads and tried to call the function and it runs fine but when I join the threads, nothing happens.
Things I tried so far
- breakpoint before
threads.each(&:join)
and call the function (works fine) - breakpoint in the rspec example and debug
operation
andparams
(all good)
any more ideas?
Edit
this is my current DatabaseCleaner configuration
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.clean_with(:deletion)
end
config.before do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, js: true) do
DatabaseCleaner.strategy = :deletion
end
config.before do
DatabaseCleaner.start
end
config.after do
DatabaseCleaner.clean
end
end
I still haven't tried to modify the strategy to :deleteion
, I will do it as well
use_transactional_fixtures
is set to false and we are using DatabaseCleaner, yes – Faller