Edm*_*Lee 5 ruby multithreading rspec ruby-on-rails factory-bot
关注此博客文章,http://blog.arkency.com/2015/09/testing-race-conditions/
我试图测试并发性.但在我的规格中,当我启动新线程或分叉进程时,我无法找到记录.
describe 'test concurrency' do
let(:order_1) { create(:order) }
let(:order_2) { create(:order) }
let(:order_3) { create(:order) }
let(:order_4) { create(:order) }
let(:product) { create(:product) }
it 'test concurrency' do
wait_for_all_threads = true
product.update(quantity_available: 4, quantity_sold: 0, quantity_in_carts: 0)
orders = [order_1, order_2, order_3, order_4]
# Objects are persisted in here
# because order_n.persisted => true
# product.persisted => true
# product.reload works without issue (and this is essentially what causes the RecordNotFound error in Order#add_item)
threads = orders.map do |order|
Thread.new do
# Objects cannot be found in the database
true while wait_for_all_threads
item = order.add_item(product, 1)
order_items << item
end
end
wait_for_all_threads = false
threads.each(&:join)
# ...
# here comes all the expects ...
# not gonna post it because it's not what matters in this question
end
end
Run Code Online (Sandbox Code Playgroud)
经过研究,我设定了这些:
DatabaseCleaner.strategy = :truncation
config.use_transactional_fixtures = false
Run Code Online (Sandbox Code Playgroud)
但没有运气.
所以问题是,在新线程中,没有任何创建的对象可以在数据库中找到.
我在挖掘的一些线索:
persisted?)after_commit不会在rspec中运行)使用 Rails 5 这对我有用。放置在描述中:
self.use_transactional_tests = false
Run Code Online (Sandbox Code Playgroud)
“use_transactional_fixtures”已被弃用。
我还必须通过以下方式绕过 DatabaseCleaner:
it 'tests concurrency', bypass_cleaner: true do
end
Run Code Online (Sandbox Code Playgroud)
然后在rails_helper中(或者你有DatabaseCleaner设置的地方)
config.around(:each) do |example|
if example.metadata[:bypass_cleaner]
example.run
else
# database cleaner code
end
end
Run Code Online (Sandbox Code Playgroud)
我希望这对您或其他人有所帮助:)
| 归档时间: |
|
| 查看次数: |
452 次 |
| 最近记录: |