提问人:Felipe Junges 提问时间:10/8/2023 更新时间:10/8/2023 访问量:39
测试:如何检查一个 sidekiq 作业是否将另一个 sidekiq 作业排入队列
Tests: How to check if a sidekiq job enqueued another sidekiq job
问:
我有这两个示例类,我想编写一个首次运行 PaymentCheckJob 的 rspec,如果payment_type == 'ticket',我想检查它是否将另一个 sidekiq 作业排入队列
class ApplicationJob
include Sidekiq::Job
sidekiq_options retry: 1
def perform(*args)
# Do something
end
end
class PaymentCheckJob < ApplicationJob
def perform(args = '{}')
args = JSON.parse(args)
invoice_id = args['invoice_id']
if invoice.payment_type == 'ticket'
::PaymentCheckJob.perform_at(1.hour.from_now, { 'invoice_id': invoice.id }.to_json)
# ::PaymentCheckJob.perform_in(3600, { 'invoice_id': invoice.id }.to_json)
else
invoice.payed_at = Time.now
end
end
end
答:
0赞
mechnicov
10/8/2023
#1
您可以存根此方法,编写两个不同的上下文:当作业排队时和未排队时
像这样的东西
require 'rails_helper'
RSpec.describe PaymentCheckJob, type: :job do
describe '#perform' do
subject(:perform_job) { described_class.new.perform(invoice_id: invoice.id) }
let(:invoice) { Invoice.create(payment_type: payment_type) }
before { allow(described_class).to receive(:perform_at) }
context 'when invoice is ticket' do
let(:payment_type) { 'ticket' }
it 'enqueues another PaymentCheckJob' do
perform_job
expect(described_class).to have_received(:perform_at)
end
end
context 'when invoice is not ticket' do
let(:payment_type) { 'not_ticket' }
it 'does not enqueue another PaymentCheckJob' do
perform_job
expect(described_class).not_to have_received(:perform_at)
end
end
end
end
您还可以检查作业大小,例如
expect { perform_job }.to change { PaymentCheckJob.jobs.size }.by(1)
expect { perform_job }.not_to change { PaymentCheckJob.jobs.size }
您还可以在文档中阅读有关测试 Sidekiq 的提示
但我不确定从另一个作业调用一个作业是个好主意。也许你可以用 cron 安排这个作业(例如每 5 分钟 1 个),而不是传递一些参数,而是在作业主体内获取这些发票的批次(例如一些范围,如 )。要排除争用条件,您可以锁定这些发票以进行更新。此外,为了确保没有两个作业同时运行,请使用咨询锁定 (mutex) 锁定 perform 方法的正文。当然,如果需要,还可以更新发票。在这种情况下,您将更多地管理流程,并且作业不会以某种方式相互调用。我认为如此Invoice.not_processed
评论