期望同一类的多个 Rails Active Jobs 使用不同的参数排队

Str*_*yer 8 ruby rspec ruby-on-rails rails-activejob

我有一个 Rails Active Job,它创建多个具有不同参数的相同类型的其他作业。我想测试该作业是否使用正确的参数将另一个作业排入队列。

这基本上就是我想要实现的目标:

require 'rails_helper'

RSpec.describe TriggerJob, type: :job do
  include ActiveJob::TestHelper

  after do
    clear_enqueued_jobs
  end

  it 'enqueues jobs for all model instances' do
    model1 = create(:model)
    model2 = create(:model)
    model3 = create(:model)

    expect { described_class.perform_now }
      .to(have_enqueued_job(ModelJob).with { |arg| expect(arg.id).to be == model1.id }.exactly(:once))
      .and(have_enqueued_job(ModelJob).with { |arg| expect(arg.id).to be == model2.id }.exactly(:once))
      .and(have_enqueued_job(ModelJob).with { |arg| expect(arg.id).to be == model3.id }.exactly(:once))
  end
end
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为 RSpec 似乎只是匹配作业类类型,然后尝试将第一个作业参数与我的块进行比较。根据队列中的顺序,此操作会失败。我希望 RSpec 匹配任何排队的 ModelJob 作业,并且只有在队列中找不到任何匹配项时才会失败。

此外,我想测试是否存在其他具有不同参数的 ModelJob 作业,但这并不是真正需要的。

Sad*_*jow 7

# ...
it 'schedules the job with different arguments' do
    described_class.perform_now

    expect(ModelJob).to(have_been_enqueued.at_least(:once).with(model1.id))

    expect(ModelJob).to(have_been_enqueued.at_least(:once).with(model2.id))

    expect(ModelJob).to(have_been_enqueued.at_least(:once).with(model3.id))
end
Run Code Online (Sandbox Code Playgroud)


Mic*_*ant 0

你可以enqueued_jobs直接检查。不过,它并不那么漂亮。

  it 'enqueues jobs for all model instances' do
    model1 = create(:model)
    model2 = create(:model)
    model3 = create(:model)

    described_class.perform_now

    job_classes = enqueued_jobs.map { |enqueued_job| enqueued_job[:job] }
    expect(job_classes).to eq([ModelJob] * 3)

    job_args = enqueued_jobs.map do |enqueued_job|
      ::ActiveJob::Arguments.deserialize(enqueued_job[:args])
    end
    expect(job_args.one? { |arg| arg.id == model1.id }).to eq(true)
    expect(job_args.one? { |arg| arg.id == model2.id }).to eq(true)
    expect(job_args.one? { |arg| arg.id == model3.id }).to eq(true)
  end
Run Code Online (Sandbox Code Playgroud)