在RSpec中使用Thread.new测试并发性

6

我正在尝试建立一个关于并发的测试。最终目标是测试使用 ActiveRecord 的服务跳过在 PostgreSQL 中被锁定的记录

这在两个控制台中运行得很好:

# in console 1
queue = MyFancyQueue.first
item_1 = queue.items.first
item_1.with_lock { sleep 30 } # locks item_1 for 30 seconds

# in console 2, while item_1 is locked
queue = MyFancyQueue.first
queue.items.first # => item_1
queue.items.lock('FOR UPDATE SKIP LOCKED').first # => item_2

然而,使用 RSpec 时,我在 Thread.new 中运行的任何代码都找不到记录,类似于:
let(:queue) { MyFancyQueue.create }
let!(:items) { create_list(:item, 2, queue: queue) }

context 'with first item locked' do
  it 'returns the second item' do
    Thread.new { queue.items.first.with_lock { sleep 30 } }

    expect(queue.items.lock('FOR UPDATE SKIP LOCKED').first).to eq items.last
  end
end

如果使用queue.items.first,会抛出找不到的错误,当使用pry查看线程时,我看不到任何项目。

我如何使用RSpec有效地测试这样的内容?


1
你的rails_helper.rb文件中是否设置了config.use_transactional_fixtures = false - Oleh Sobchuk
@OlegSobchuk 它被设置为真。 - martini-bonanza
将其更改为“false”,然后再尝试一次。 - Oleh Sobchuk
1个回答

2

如果你使用DatabaseCleaner,请确保在此测试中设置 DatabaseCleaner.strategy = :truncation


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接