0

我有以下工人

class JobBlastingWorker
  include Sidekiq::Worker
  sidekiq_options queue: 'job_blasting_worker'

  def perform(job_id, action=nil)
    job = Job.find(job_id)

    JobBlastingService.new(job).call
    sidekiq_id = JobBlastingWorker.perform_in(2.minutes, job.id, 're-blast', true)
    job.sidekiq_trackers.create(sidekiq_id: sidekiq_id, worker_type: 'blast_version_update')
  end
end

在我的 rspec 测试中,我有以下内容job_blasting_worker_spec.erb

require 'rails_helper'

describe JobBlastingWorker do
  before(:all) do
    Rails.cache.clear
  end

  describe 'perform' do
    context 'create' do
      it 'creates job schedule for next 2mins' do
        @job = create(:job)
        worker = JobBlastingWorker.new
        expect(JobBlastingWorker).to have_enqueued_sidekiq_job(@job.id, 're-blast').in(2.minutes)
        worker.perform(@job.id, 'create')
      end
    end
  end
end

我希望这能奏效,但我意识到应该安排在接下来的 2 分钟内的 sidekiq 作业永远不会被创建。因此,测试失败。

我如何确保 sidekiq 作业在接下来的 2 分钟内实际创建并且测试成功运行?

4

1 回答 1

1

嗯...对于这种期望,我建议只是测试发送到方法的消息。

  expect(JobBlastingWorker).to have_enqueued_sidekiq_job(@job.id, 're-blast')
  expect(JobBlastingWorker).to receive(:perform_in).with(2.minutes, job.id, 're-blast', true).and_call_original
  worker = JobBlastingWorker.new
  worker.perform(@job.id, 'create')

当然,如果你真的努力挖掘,我想你最终会找到一种方法来找到队列中的活动作业对象,例如直接使用 Redis API。
然后您可以进一步检查对象并获取您为要执行的工作设置的时间。
但为什么?这是 ActiveJob 的责任,以确保这些工作将在正确的时间执行。
发现这一点对您没有多大帮助,并且这种行为应该已经在 RSpec 的测试中进行了测试。
我认为您不必担心,除非它工作不正常并且您想重现这种情况并发出错误。

另一方面,您发送到方法的时间是您应该关心的。您不希望有人2.hours意外将其更改为。
所以我建议你应该测试你发送给方法的消息。

于 2021-09-22T05:56:56.833 回答