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

Rails中用RSpec测试含Sidekiq Batch的Job:batch为nil错误排查

问题根源

报错undefined method 'jobs' for nil:NilClass是因为测试环境中没有模拟Sidekiq Batch的上下文:

  • 实际运行时,AnotherWorker是在ParentWorker的batch.jobs块里被调用的,Sidekiq会自动将当前Batch实例注入到子Job的执行环境中,所以batch变量能直接使用。
  • 但测试时是直接调用AnotherWorker.perform,没有触发Sidekiq的Batch上下文注入,导致batch为nil。
修正后的测试代码
describe AnotherWorker, type: :job do
  describe '#perform' do
    subject { described_class.new.perform(asset_id) }

    let(:asset_id) { create(:asset).id }
    let(:batch) { instance_double(Sidekiq::Batch) }

    before do
      # 模拟Sidekiq Batch的当前上下文,让AnotherWorker能拿到batch实例
      allow(Sidekiq::Batch).to receive(:current).and_return(batch)
      # 模拟batch.jobs块的执行逻辑
      allow(batch).to receive(:jobs).and_yield
    end

    it 'enqueues ThirdJobWorker 3 times' do
      subject

      # 注意:原业务代码中ThirdJobWorker.perform_async未传asset_id,需与实际逻辑匹配
      expect(ThirdJobWorker).to have_enqueued_sidekiq_job.exactly(3).times
    end
  end
end
关键修正点
  • 用allow(Sidekiq::Batch).to receive(:current).and_return(batch)模拟Sidekiq Batch的当前上下文,让AnotherWorker中的batch变量指向mock实例。
  • 修正ThirdJobWorker的入参期望:原业务代码里ThirdJobWorker.perform_async没有传递asset_id,测试需与实际逻辑一致,否则会断言失败。
  • 移除重复的expect(batch).to receive(:jobs).and_yield,避免因重复定义mock导致的期望不匹配。
额外说明

如果需要测试ParentWorker与AnotherWorker的联动逻辑(比如验证ParentWorker触发后,AnotherWorker是否正确入队到Batch中),可单独编写测试用例,模拟Team和Asset的关联关系,验证入队行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:28:20