35

我正在尝试为自定义延迟作业 (GetPage::GetPageJob) 运行 rspecs,但我遇到了问题。

当我运行它们时,这些作业被很好地排入队列(也就是说,很好地插入到了delayed_jobs 表中),但它们没有被作业工作者处理。实际上,在第一个终端中启动“rake jobs:work RAILS_ENV=test”之后,在第二个终端中运行规范后,我在第一个终端中看不到作业工作者的任何输出。

另一方面,如果我通过“脚本/控制台测试”将它们排入队列,这些作业就会得到很好的处理。所以我有点困惑。

使用规范和脚本/控制台,我用来排队我的工作的行是:

Delayed::Job.enqueue GetPage::GetPageJob.new("http://cnn.com")

任何想法 ?

4

4 回答 4

97

在 RSpec 中测试排队的 Delayed::Job 任务的最简单方法是实时运行它们。只需将以下行添加到您的 RSpec 测试中:

Delayed::Worker.delay_jobs = false

这将导致您的作业在排队时立即处理,而不是在单独的线程中。这通常是您想要测试的内容,因为它是确定性的。

两个警告

  • 如果您尝试测试计时错误、竞争条件等,这种方法将无济于事(因为作业是在与 RSpec 相同的线程中处理的)

  • Delayed::Worker.delay_jobs当前版本的delayed_job (2.1.4) 有一个小错误,当设置为false 时,不会调用回调挂钩(入队、之前、成功、错误、失败) 。

两种解决方法

如果您需要测试回调挂钩,我知道两种解决方法:

  • 从 github 获取最新的 master 分支。(我没有尝试过,因为我需要一个稳定的版本)

  • 代替设置Delayed::Worker.delay_jobs = false,在测试代码中显式调用 DJ 的运行机制,如下所示:

    successes, failures = Delayed::Worker.new.work_off

这将处理作业队列中的任何内容(同样,在与 RSpec 测试相同的线程中)并返回两个数字:成功的作业数和失败的作业数。我目前使用这种方法,它可以满足我的一切需求。

于 2011-08-16T02:31:55.200 回答
3

您需要从测试内部而不是从另一个进程启动工作进程。尝试:

worker = Delayed::Worker.new(:max_priority => nil, :min_priority => nil, :quiet => true)
worker.work_off
于 2011-01-09T15:11:56.710 回答
3

过去,我尝试对逻辑进行端到端测试 -> 延迟作业 -> 执行作业,结果太多了。我认为,与其使用 RSpec 测试完整的甜蜜,不如专注于测试每个方面。

因此,测试一个作业是否被插入。然后,进行另一个测试来测试执行作业时应该发生的情况。

或者,模拟延迟作业,这样当您将作业排入队列时,它会立即执行它。

于 2010-07-17T00:34:48.567 回答
1

我使用配置选项实时运行作业:

# config/initializers/delayed_job_config.rb
Delayed::Worker.delay_jobs = !Rails.env.test?
于 2013-09-04T08:12:51.813 回答