RSpec测试验证Sidekiq::Limiter.unlimited被调用报错排查
问题根因
核心问题是Op::QueueProcessing::LIMITER属于类常量,Ruby会在类首次被加载时就执行throttle方法完成常量赋值。你的测试用例中对Sidekiq::Limiter.unlimited的打桩操作是在类加载完成后的测试执行阶段才执行,此时throttle方法早已调用完成,自然无法统计到调用记录。
可选解决方案
方案1:修改实现为惰性求值(推荐)
将原有固定赋值的类常量改为动态获取的类方法,只有首次用到时才会执行环境判断逻辑,适配测试打桩时机:
# 修改后的Worker类代码 module Op class QueueProcessing include Sidekiq::Worker def self.throttle return Sidekiq::Limiter.unlimited if Rails.env.test? Sidekiq::Limiter.concurrent( 'analytics', 1, wait_timeout: 5, lock_timeout: 120 ) end # 替换原有LIMITER常量为惰性加载的类方法 def self.limiter @limiter ||= throttle end def perform uploaded_submissions = OnClaimsSubmission.uploaded_submissions uploaded_submissions.each do |submission| self.class.limiter.within_limit do Op::ProcessDownloadedFiles.perform_async(*submission) end end end end end
原有测试用例无需修改即可正常运行。
方案2:调整测试逻辑,直接验证常量类型
如果不想修改原有实现,可以直接校验测试环境下常量的类型是否符合预期,无需校验方法调用:
# 修改后的测试用例代码 # frozen_string_literal: true require 'rails_helper' describe Op::QueueProcessing do describe 'concurrency' do it 'uses unlimited limiter in test environment' do expect(described_class::LIMITER).to be_a(Sidekiq::Limiter::Unlimited) end end end
该方案无需修改业务代码,执行效率更高。
内容的提问来源于stack exchange,提问作者fatfrog
相关产品推荐
相关产品推荐

