我最近一直在使用 Rabbitmq 和 Sneakers Workers 开发消息队列。我看过这个指南https://github.com/jondot/sneakers/wiki/Testing-Your-Worker

但是我仍然不知道如何为他们开发测试。如果有任何建议,我将不胜感激。

请您参考如下方法:

建议的指南包含 Sneakers::Testing模块来存储所有发布的消息。为此,您需要修补/ stub 方法 Sneakers::Publisher#publish将发布的消息保存到 Sneakers::Testing.messages_by_queue .然后将这些数据用于预期或以某种方式将数据提供给 worker 类(Class)。
可能在大多数情况下,您只需要内联执行规范中的延迟作业。所以可以只打补丁Sneakers::Publisher#publish通过队列名称获取工作类并调用其work接收到有效载荷消息的方法。初始设置:

# file: spec/support/sneakers_publish_inline_patch.rb 
 
# Get list of all sneakers workers in app. 
# You can just assign $sneakers_workers to your workers: 
# 
#     $sneakers_workers = [MyWorker1, MyWorker2, MyWorker3] 
# 
# Or get all classes where included Sneakers::Worker 
# Note: can also load all classes with Rails.application.eager_load! 
Dir[Rails.root.join('app/workers/**/*.rb')].each { |path| require path } 
$sneakers_workers = ObjectSpace.each_object(Class).select { |c| c.included_modules.include? Sneakers::Worker } 
 
# Patch method `publish` to find a worker class by queue and call its method `work`. 
module Sneakers 
  class Publisher 
    def publish(msg, opts) 
      queue = opts[:to_queue] 
      worker_class = $sneakers_workers.find { |w| w.queue_name == queue } 
      worker_class.new.work(msg) 
    end 
  end 
end 
或规范中一名 worker 的 stub 方法:
allow_any_instance_of(Sneakers::Publisher).to receive(:publish) do |_obj, msg, _opts| 
  MyWorker.new.work(msg) 
end 
或者添加一个共享上下文以方便地启用内联作业执行:
# file: spec/support/shared_contexts/sneakers_publish_inline.rb 
 
shared_context 'sneakers_publish_inline' do 
  let(:sneakers_worker_classes) do 
    Dir[Rails.root.join('app/workers/**/*.rb')].each { |f| require f } 
    ObjectSpace.each_object(Class).select { |c| c.included_modules.include? Sneakers::Worker } 
  end 
 
  before do 
    allow_any_instance_of(Sneakers::Publisher).to receive(:publish) do |_obj, msg, opts| 
      queue = opts[:to_queue] 
      worker_class = sneakers_worker_classes.find { |w| w.queue_name == queue } 
      raise ArgumentError, "Cannot find Sneakers worker class for queue: #{queue}" unless worker_class 
      worker_class.new.work(msg) 
    end 
  end 
end 
 
然后只需添加 include_context 'sneakers_publish_inline'在您需要内联作业执行的规范中。


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!