【问题标题】:Delayed Job not processed in rspecrspec 中未处理延迟作业
【发布时间】:2011-03-12 15:18:18
【问题描述】:

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

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

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

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

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

有什么想法吗?

【问题讨论】:

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


    【解决方案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?
      

      【讨论】:

        猜你喜欢
        • 2014-12-22
        • 2011-08-30
        • 2011-09-15
        • 1970-01-01
        • 2012-03-29
        • 1970-01-01
        • 2017-11-08
        • 1970-01-01
        • 2012-03-24
        相关资源
        最近更新 更多