You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写RSpec测试验证Sidekiq Worker异步调用的传入参数是否正确

你的测试存在三个核心问题

  • 重复声明ScoringWorker.perform_async的期望:第二次无参数匹配的expect(ScoringWorker).to receive(:perform_async).exactly(1).times会覆盖第一次带参数校验的期望,导致参数校验逻辑失效,触发参数不匹配报错
  • 多余的JobBlastingWorker.perform_in期望:你的现有业务代码中没有任何调用perform_in的逻辑,这条无厘头的期望会直接触发测试失败
  • 不需要加and_call_original:如果你只是要验证参数是否正确,不需要真的执行ScoringWorker的逻辑,加了反而可能引入额外的数据库操作等依赖

正确的测试写法

写法1:使用rspec-sidekiq gem(推荐,语法更简洁)

首先确保你在Gemfile的test组里添加了rspec-sidekiq依赖,测试代码如下:

require 'rails_helper'

RSpec.describe JobBlastingWorker do
  describe '#perform' do
    context 'when action is create' do
      it 'triggers ScoringWorker with correct parameters' do
        job = create(:job)
        # 执行worker逻辑
        described_class.new.perform(job.id, 'create')
        # 验证ScoringWorker的入参符合预期
        expect(ScoringWorker).to have_enqueued_sidekiq_job(job.id, 0, 'create').exactly(1).times
      end
    end
  end
end

写法2:手动mock(不需要额外依赖)

require 'rails_helper'

RSpec.describe JobBlastingWorker do
  describe '#perform' do
    context 'when action is create' do
      it 'triggers ScoringWorker with correct parameters' do
        job = create(:job)
        # 只声明一次带参数校验的期望即可
        expect(ScoringWorker).to receive(:perform_async).with(job.id, 0, 'create').exactly(1).times
        # 执行worker逻辑
        described_class.new.perform(job.id, 'create')
      end
    end
  end
end

额外注意事项

如果需要真的执行异步任务的逻辑做集成测试,可以打开Sidekiq的测试内联模式:

Sidekiq::Testing.inline! do
  described_class.new.perform(job.id, 'create')
end

这种模式下所有异步任务会同步执行,你可以额外验证后续的业务逻辑(比如job的version是否被正确更新为0)。

内容的提问来源于stack exchange,提问作者Kingsley Simon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 17:45:03