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 中未处理延迟作业的主要内容,如果未能解决你的问题,请参考以下文章

Rspec 测试延迟作业

使用 rSpec 测试延迟作业链的最佳方法是啥?

Laravel 排队的作业即使有延迟也会立即处理

如何查询延迟作业处理程序

何时使用 - 延迟作业与 RabbitMQ

将块传递给延迟作业