ruby-on-rails - 测试运动鞋和 Rabbitmq 的 RSpec
问题描述
我最近一直在使用 Rabbitmq 和 Sneakers Workers 开发消息队列。我查看了本指南https://github.com/jondot/sneakers/wiki/Testing-Your-Worker
但是我仍然不知道如何为他们开发测试。如果有任何建议,我将不胜感激。
解决方案
建议的指南包含Sneakers::Testing
存储所有已发布消息的模块。为此,您需要修补/存根方法Sneakers::Publisher#publish
以将发布的消息保存到Sneakers::Testing.messages_by_queue
. 然后将这些数据用于预期或以某种方式将数据提供给工人阶级。
可能在大多数情况下,您只需要内联执行规范中的延迟作业。因此可以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
或规范中一名工人的存根方法:
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'
在需要执行内联作业的地方添加规范。
推荐阅读
- logging - 在 AnyLogic 中重置运行时日志
- apache-flink - 从进程元素内的多个线程读取 flink MapState 键值会引发 ConcurrentModification 异常
- node.js - 无法将日期转换为猫鼬中的字符串格式日期
- python - 如何在将 .py 转换为 .exe 时添加图像文件?
- socket.io - NativeScript 和 SocketIO:找不到变量:SocketManager
- java - Spring 控制器向 AngularJS 应用程序的请求返回 415
- java - 应用小部件在某些设备中无法连接到服务器
- java - 为什么位置在 android 10 的应用程序中不起作用?
- apache-kafka - Kafka 连接在 docker 中找不到代理
- javascript - 无法连接到我的 MongoDB 数据库,在 Mongodb Compass 上收到此错误“Server Selection Timed Out After 3000ms”