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

标签 ruby-on-rails ruby multithreading rspec

运行下面列出的规范时出错。它不会等待线程完成并取消对迁移方法的 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/

相关文章:

java - JUnit 和 Ruby 测试集成

.net - Rx .NET : Filter observable until task is done

c - Windows 中的高级 C 编程(pthreads、信号和信号量,天哪!)

php - 如何在 PHP 中正确分离和删除 2 个进程之间的共享内存?

css - Rails App 中的样式表范围不正确

html - simple_form 嵌套 json 属性

ruby-on-rails - 从 Selenium 更改为 Capybara-Webkit 后出现 cache_classes/Spork 问题

css - 如何在 RoR 应用程序中为背景视频调试 HTML5/CSS

css - 如何使用 css、字形和符号格式化 f.submit?

ruby-on-rails - 设计不使用自定义邮件 View