【问题标题】:Testing concurrency with Thread.new in RSpec在 RSpec 中使用 Thread.new 测试并发性
【发布时间】:2016-12-15 23:39:45
【问题描述】:

我正在尝试围绕并发进行测试。最终目标是使用 ActiveRecord skips locked records in 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 有效地测试类似的东西?

【问题讨论】:

  • 在您的 rails_helper.rb 中是 config.use_transactional_fixtures = false 吗?
  • @OlegSobchuk 设置为 true
  • 改成false再试一次

标签: ruby-on-rails ruby multithreading postgresql rspec


【解决方案1】:

如果您使用 DatabaseCleaner,请确保 DatabaseCleaner.strategy = :truncation 用于此测试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多