在HTTP上下文之外调度Rails控制器操作(不在单元测试中)

时间:2018-06-12 12:19:16

标签: ruby-on-rails ruby actioncontroller actiondispatch

我维护了一个使用Rails作为API的成熟代码库。 Rails应用程序还使用MQTT(实时,非Web,非HTTP协议)执行某些操作。

有些用户要求能够通过MQTT协议模拟相同的REST命令(避免需要两次授权并拥有两个不同的协议客户端)。

我见过一些项目,such as Facebook's API通过将部分HTTP请求放入使用JSON的请求中来“模拟”HTTP(例如:在JSON有效负载上有一个“header”和“method”属性)。这正是我想要做的事情,但完全在HTTP上下文之外。它将在处理MQTT消息的后台工作程序中发生。

是否可以使用ActionDispatch和朋友单独模拟控制器调度?

我很难找到有关如何在RSpec之外单独实例化ActionDispatch::Request对象的文档。

MyController.dispatch("create",
                     ActionDispatch::Request.new({"???" => "Can't find any docs on this one."}),
                     ActionDispatch::Response.new("?"))
# => RuntimeError: Missing rack.input

1 个答案:

答案 0 :(得分:2)

非常有趣的问题!

我的第一个想法是向后处理它:所以创建一个假的ofstreamRack::Request,然后强制它被处理?假设它将自动转到正确的控制器和动作(因此您不必明确地调用它)。但当然问题仍然存在:如何创建ActionDispatch::Request :)

所以我正在浏览rails测试,我找到了以下片段,可能会让你开始:

Request

来源:https://github.com/rails/rails/blob/85fcb663363cd27220e8bd3136973cc3408cf7d7/actionpack/test/controller/metal_test.rb

根据我的理解,这意味着您可以将整个虚假请求环境作为哈希,键是字符串,对吧?因此,您可以从有效请求转储env并相应地进行转置。

不确定这是否真的有用。