rspec 中未处理延迟作业
Posted
技术标签:
【中文标题】rspec 中未处理延迟作业【英文标题】:Delayed Job not processed in rspec 【发布时间】:2011-03-12 15:18:18 【问题描述】:我正在尝试为自定义延迟作业 (GetPage::GetPageJob) 运行 rspecs,但我遇到了问题。
当我运行它们时,这些作业被很好地排队(也就是说,很好地插入到了延迟作业表中),但它们没有被作业工作者处理。 事实上,在第一个终端中启动“rake jobs:work RAILS_ENV=test”后,在第二个终端中运行规范后,我在第一个终端中看不到作业工作者的任何输出。
另一方面,如果我通过“脚本/控制台测试”将作业排入队列,则作业会得到很好的处理。 所以我有点困惑。
使用规范和脚本/控制台,我用来排队我的工作的行是:
Delayed::Job.enqueue GetPage::GetPageJob.new("http://cnn.com")
有什么想法吗?
【问题讨论】:
【参考方案1】:过去,我尝试对逻辑进行端到端测试 -> 延迟作业 -> 执行作业,结果太多了。我认为与其使用 RSpec 测试完整的甜蜜,不如专注于测试各个方面。
所以,测试一个作业是否被插入。然后,进行另一个测试来测试执行作业时应该发生的情况。
或者,模拟延迟作业,这样当您将作业排入队列时,它会立即执行。
【讨论】:
我发现你的最后一句话很有用;我只是做任何一个,例如UserMailer.stub(delay: UserMailer)
或 obj.stub(delay: obj)
和我的测试卡车愉快地前进。虽然在配置Delayed::Worker.delay_jobs = !Rails.env.in?(['development', 'test'])
中执行此操作的建议也可以,但我有一大堆遗留测试正在测试我现在不想更新的延迟作业本身。谢谢!【参考方案2】:
您需要从测试内部而不是从另一个进程启动工作进程。试试:
worker = Delayed::Worker.new(:max_priority => nil, :min_priority => nil, :quiet => true)
worker.work_off
【讨论】:
【参考方案3】:在 RSpec 中测试排队的 Delayed::Job 任务的最简单方法是实时运行它们。只需将以下行添加到您的 RSpec 测试中:
Delayed::Worker.delay_jobs = false
这将导致您的作业在排队时立即处理,而不是在单独的线程中。这通常是您想要测试的内容,因为它是确定性的。
两个注意事项
如果您尝试测试计时错误、竞争条件等,这种方法将无济于事(因为作业与 RSpec 在同一线程中处理)
当前版本的delayed_job (2.1.4) 有一个小错误,当Delayed::Worker.delay_jobs
设置为false 时,不会调用回调挂钩(入队、之前、成功、错误、失败)。
两种解决方法
如果您需要测试回调挂钩,我知道有两种解决方法:
从 github 获取最新的 master 分支。 (我没有尝试过,因为我需要一个稳定的版本)
不要设置Delayed::Worker.delay_jobs = false
,而是在您的测试代码中显式调用DJ的运行机制,如下所示:
successes, failures = Delayed::Worker.new.work_off
这将处理作业队列中的任何内容(同样,在与 RSpec 测试相同的线程中)并返回两个数字:成功的作业数和失败的作业数。我目前使用这种方法,它可以满足我的一切需求。
【讨论】:
您的回答非常聪明、完整且有据可查:)。谢谢,你让我很开心:) :attempts 怎么样?你如何测试它? @oma:也许我误解了你,但是 [successes, failures] 返回值考虑了 :attempts :在超过 :attempts 的数量之前,作业实际上不会失败。 不想劫持这个帖子。也许我会写一个 Q。我正在为每个作业设置 max_attempts,实现方法错误和重新安排(DJ 用 responds_to 寻找?)。我很难测试它是否进行了更多尝试...... 语法不太正确,没有 [ ] 围绕分配成功和失败successes, failures = Delayed::Worker.new.work_off
【参考方案4】:
我使用配置选项实时运行作业:
# config/initializers/delayed_job_config.rb
Delayed::Worker.delay_jobs = !Rails.env.test?
【讨论】:
以上是关于rspec 中未处理延迟作业的主要内容,如果未能解决你的问题,请参考以下文章