【发布时间】:2021-11-13 11:09:20
【问题描述】:
我正在尝试通过 RSpec 测试 API 的竞争条件。 我有一个员工表,其中employee_code 需要是唯一的。 如果有多个员工具有相同的代码,系统将自动添加代码与它的工作。现在我想测试当多个相同代码员工尝试同时创建员工时它是否有效。
threads = []
wait = true
4.times do |i|
threads << Thread.new do
true while wait
submit_request example.metadata
end
end
wait = false
threads.each(&:join)
我为此添加了截断配置
config.around(:each, use_transactional_fixtures: false) do |example|
config.use_transactional_fixtures = false
example.run
config.use_transactional_fixtures = true
end
我的规格是:
describe "concurrent create employee request", use_transactional_fixtures: false do
before do
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.start
end
after do
DatabaseCleaner.clean
end
context "multiple login enabled" do
context "should save all" do
let(:params) { { employee: { employee_code: "employee" } } }
before do
allow(Time.zone).to receive(:now).and_return(Time.zone.now)
end
before do |example|
threaded_api_request(example)
end
it do
expect(Employee.count).to eq 4
end
end
end
end
但我的问题是虽然所有线程都在执行,但并非所有线程都在调用导致我的规范失败的 API(有时 2 或 3 次)。我是不是做错了什么?
【问题讨论】:
-
当您的规格失败时,您会得到什么错误?您用来生成唯一代码的代码看起来如何?数据库中是否有唯一索引以避免重复?
-
@spickermann 我得到了预期的 4,得到:1/2/3 我在控制器和线程的代码中设置了一些日志注释。我看到线程评论总是打印 4 次,但控制器中的评论显示 1/2/3 次我正在使用咨询锁以及带有救援块的唯一索引,但我也从不进入救援块
标签: ruby-on-rails ruby rspec