使用delayjob的ActiveJob不会在测试中创建delay_jobs行

问题描述 投票:4回答:1

在Rails 4.2.3中,我已经设置ActiveJob在所有环境中都将delay_job用作其后端:

environment.rb

require File.expand_path('../boot', __FILE__)

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module MyApp
  class Application < Rails::Application
    # ... snip
    # Use delayed_job for Active Job queueing
    config.active_job.queue_adapter = :delayed_job
  end
end

((在配置中未设置queue_adapter

我已经按如下方式配置了我的DelayedJob实例-包括来自this question的代码以反向移植Rails 5的功能以获取作业的数据库行:

config / delayedjob.rb

Delayed::Worker.destroy_failed_jobs = false
Delayed::Worker.sleep_delay = 60
Delayed::Worker.max_attempts = 3
Delayed::Worker.max_run_time = 5.minutes
Delayed::Worker.read_ahead = 10
# Delayed::Worker.delay_jobs = true #!Rails.env.test?
Delayed::Worker.logger = Logger.new(Rails.root.join('log', 'delayed_job.log'))

class Delayed::Job < ActiveRecord::Base
  belongs_to :owner, polymorphic: true
end

# Backport Rails 5 code to make the Delayed::Job database id avilable on ActiveJobs
module ActiveJob
  module Core
    # ID optionally provided by adapter
    attr_accessor :provider_job_id
  end

  module QueueAdapters
    class DelayedJobAdapter
      class << self
        send(:prepend, Module.new do
          def enqueue(job)
            provider_job = super
            job.provider_job_id = provider_job.id
            provider_job
          end

          def enqueue_at(job, timestamp)
            provider_job = super
            job.provider_job_id = provider_job.id
            provider_job
          end
        end)
      end
    end
  end
end

我有模型代码可以稍后执行工作,并将Delayed::Job实例挂接到模型实例上:

app / models / my_model.rb

def schedule
  job = MyJob.set(wait_until: scheduled_time).perform_later(self)

  # Associate the delayed_job object with the item that has been scheduled
  delayed_job = Delayed::Job.find(job.provider_job_id)
  delayed_job.owner = self
  delayed_job.save
end

(并且我已经为Delayed::Job建立了适当的关联。

这似乎在开发中工作良好;但在测试中,Delayed::Job.find(job.provider_job_id)失败并引发异常,因为provider_job_id为零。检查日志显示delayed_jobs表没有SQL INSERT。

为什么在测试中没有创建延迟的作业行?

ruby-on-rails delayed-job ruby-on-rails-4.2 rails-activejob
1个回答
0
投票

我也遇到同样的问题。事实证明,ActiveJob::TestCase劫持了perform_later逻辑,并且实际上并未将它们排队,而是将有关排队作业的数据存储在数组(see here)中。

我的解决方案是编写一个从ActiveSupport::TestCase继承的测试,这似乎像正常情况一样将延迟的作业排队。我相信有一些测试设置将强制作业以内联方式执行,但是据我所知,默认行为是将它们排队,因此它应该可以按预期工作,而无需进行过多修改。

© www.soinside.com 2019 - 2024. All rights reserved.