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

如何用RSpec统计递归调用自身的Worker的执行次数?

测试Myworker递归调用次数的正确方案

问题根源

你之前的错误在于完全Stub掉了perform_async的原逻辑——只做了计数,但没有让Worker实际执行递归调用,所以只会统计到第一次触发,后续递归根本没跑起来。

解决思路

要在保留perform_async原执行逻辑的前提下,统计它的调用次数。这样递归能正常触发,次数统计也准确。

具体实现

1. 准备测试数据

先创建足够多的关联记录,确保Worker会触发多次递归。比如创建2500条Mymodel.users,每次删1000,需要2次递归调用(加上手动执行的1次,总共3次perform执行)。

2. 用and_call_original追踪调用

使用RSpec的allow配合and_call_original,既能统计调用次数,又不会阻止原方法执行。

3. 测试代码示例

RSpec.describe Myworker, type: :worker do
  let(:model) { Mymodel.create! }

  before do
    # 生成足够触发递归的测试数据
    2500.times { model.users.create! }
    # 追踪perform_async调用,同时保留原方法逻辑
    allow(Myworker).to receive(:perform_async).and_call_original
    # 如果用Sidekiq,开启inline模式让任务同步执行
    Sidekiq::Testing.inline! if defined?(Sidekiq)
  end

  it "正确统计递归调用次数" do
    # 手动执行第一次perform
    described_class.new.perform(model.id)
    # 断言perform_async被调用2次(对应两次递归)
    expect(Myworker).to have_received(:perform_async).exactly(2).times
  end
end

关键说明

  • and_call_original是核心:它会先让RSpec记录调用,再执行原方法的逻辑,这样递归调用能正常触发,次数统计也不会漏。
  • 如果用Sidekiq,必须开inline模式,否则异步任务会放入队列而不立即执行,导致统计不到后续的递归调用。
  • 测试后记得清理数据库,避免数据残留影响其他测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 12:47:49