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

如何用RSPEC测试缓存在常量中的Sidekiq::Limiter方法调用

问题根因

你遇到的测试失败是因为Ruby类的常量是在类加载阶段完成初始化的,早于所有测试用例的Mock逻辑执行时机。你写的验证Sidekiq::Limiter.receive(:concurrent)的用例执行时,Processier::LIMITER已经完成赋值,自然捕获不到更早的concurrent方法调用。


可落地解决方案

方案1:将常量改为懒加载实现(业务侵入最小,推荐)

修改原有常量为类级别的懒加载方法,避免类加载阶段就初始化限流器:

class Processier
  include Sidekiq::Worker

  def self.limiter
    @limiter ||= Sidekiq::Limiter.concurrent('analytics', 1, wait_timeout: 5, lock_timeout: 120)
  end

  def perform
    uploaded_submissions.each do |submission|
      self.class.limiter.within_limit do
        ProcessDownloadedFiles.perform_async(*submission)
      end
    end
  end
end

对应测试用例可以直接捕获方法调用:

# RSpec 示例
it '调用了参数正确的并发限流器' do
  expect(Sidekiq::Limiter).to receive(:concurrent).with(
    'analytics', 1, wait_timeout: 5, lock_timeout: 120
  ).and_call_original
  Processier.new.perform
end

方案2:测试阶段强制重置常量(零业务侵入)

如果不想修改业务代码,可以在测试执行前清除已经初始化的常量,强制触发concurrent方法重新调用:

# RSpec 示例
it '验证Sidekiq::Limiter收到concurrent调用' do
  # 提前清除已初始化的常量
  Processier.send(:remove_const, :LIMITER) if Processier.const_defined?(:LIMITER)
  # 设置mock期望
  expect(Sidekiq::Limiter).to receive(:concurrent).with(
    'analytics', 1, wait_timeout: 5, lock_timeout: 120
  )
  # 引用常量触发初始化,或者直接执行perform逻辑
  Processier.new.perform
end

# 测试结束后恢复常量,避免影响其他用例
after do
  Processier.send(:remove_const, :LIMITER) if Processier.const_defined?(:LIMITER)
  Processier.const_set(:LIMITER, Sidekiq::Limiter.concurrent('analytics', 1, wait_timeout: 5, lock_timeout: 120))
end

方案3:直接Stub限流器实例

如果你的测试目标是验证within_limit逻辑被正确调用,不需要校验concurrent方法的入参,可以直接Stub常量:

# RSpec 示例
it '正确通过限流器执行异步任务' do
  mock_limiter = instance_double(Sidekiq::Limiter::Concurrent)
  stub_const("Processier::LIMITER", mock_limiter)
  # 假设本次执行有3个submission,验证限流器被调用3次
  expect(mock_limiter).to receive(:within_limit).exactly(3).times.and_yield
  Processier.new.perform
end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 21:36:02