rspec中未处理延迟作业

时间:2010-07-07 04:20:47

标签: ruby-on-rails rspec delayed-job

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

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

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

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

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

有什么想法吗?

4 个答案:

答案 0 :(得分:93)

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

Delayed::Worker.delay_jobs = false

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

两个警告

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

  • 当前版本的delayed_job(2.1.4)有一个小错误,当Delayed::Worker.delay_jobs设置为Delayed::Worker.delay_jobs = false时,不会调用回调挂钩(enqueue,before,success,error,failure)假。

两个解决方法

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

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

  • 不是设置successes, failures = Delayed::Worker.new.work_off,而是在测试代码中明确调用DJ的运行机制,如下所示:

    {{1}}

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

答案 1 :(得分:3)

过去,我曾尝试对逻辑进行端到端测试 - >延迟工作 - >执行工作,这太多了。我认为,不是使用RSpec测试完全甜蜜,而是可以专注于测试每个方面。

因此,测试是否插入了作业。然后,进行另一项测试,测试作业执行时应该发生什么。

或者,模拟延迟作业,这样当你排队作业时,它立即执行。

答案 2 :(得分:3)

您需要从测试中启动工作进程,而不是从其他进程启动。尝试:

worker = Delayed::Worker.new(:max_priority => nil, :min_priority => nil, :quiet => true)
worker.work_off

答案 3 :(得分:1)

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

# config/initializers/delayed_job_config.rb
Delayed::Worker.delay_jobs = !Rails.env.test?