gpt4 book ai didi

ruby-on-rails - Rspec 应该等待线程完成

转载 作者:数据小太阳 更新时间:2023-10-29 08:39:01 25 4
gpt4 key购买 nike

运行下面列出的规范时出错。它不会等待线程完成并取消对迁移方法的 stub ,从而导致其中一个线程命中真正的方法。
注意到它只发生在加载 rails 的情况下,没有它们它可以正常工作或完成得更快......

规范:

it "should not allow infinit recursion" do
runner.stub(total_records: 4)
runner.stub(:fetch_records_batch).and_return([:one, :two])
runner.should_receive(:migrate).at_most(100).times
expect { runner.run }.to raise_error(Exception, /Migration fall into recursion/)
end

it "should pass"
1.should eq 1
end

提取的一段代码:

class Runner
def migrate(record)
raise NotImplementedError
end

def run
while have_records?(records = fetch_records_batch)
threads = []
records.each do |record|
threads << Thread.new(record) do |thread_record|
begin
result = migrate(thread_record)
rescue RuntimeError => exception
register_event :record_migration_error, thread_record, exception
end
end
recursion_preventer
end
threads.each(&:join)
end
end

def recursion_preventer
@counter ||= 0
@counter += 1
raise Exception, "Migration fall into recursion. Check logs." if @counter > (total_records * 1.1).round + 10
end
end

最佳答案

您始终可以模拟 Thread 类以简单地不启动线程,而是运行代码,我发现这比按照您建议的方式重写测试更具侵入性。

将此添加到您的测试类:

describe MyClass do
before(:each) do
allow(Thread).to receive(:new).and_yield
end
#Your normal unaltered tests under here
end

这种方法的缺点是您不会遇到竞争条件,因此代码仍然可能包含诸如“线程 a 和线程 b 同时写入同一个变量,从而导致问题”之类的错误。您还应该考虑死锁情况,因为依赖其他线程来完成某些事情的代码很可能会使用这种方法锁定。

关于ruby-on-rails - Rspec 应该等待线程完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16102037/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com