如何在 minitest 中模拟和验证 ActionCable 传输?

Posted

技术标签:

【中文标题】如何在 minitest 中模拟和验证 ActionCable 传输?【英文标题】:How do I mock and verify an ActionCable transmission in minitest? 【发布时间】:2018-10-01 08:37:57 【问题描述】:

我正在使用带有 ActionCable 的 Ruby on Rails 5.1。我想使用 minitest 测试特定方法,并模拟“ActionCable.server.broadcast”调用以验证我发送的数据是否正确

module MyModule
  class Scanner

    def trasmit
    ...
        ActionCable.server.broadcast "my_channel", data: msg_data

但我不知道如何在我的 minitest 类中验证 ActionCable 广播的消息数据是否正确。

【问题讨论】:

【参考方案1】:

Rails ActionCable source 已经过充分的测试以确保它可以正常工作,因此我们知道只要使用正确的参数调用 ActionCable,广播就可以工作。

如果您有一个套接字繁重的应用程序,我建议您尝试action-cable-testing,它有很多帮助程序来验证 ActionCable 是否确实在广播某些内容。

您可以检查您的方法是否向特定频道广播 X 次:

class ScannerTest < ActionDispatch::IntegrationTest
    include ActionCable::TestHelper

    def test_my_broadcaster
       channel_name = 'my_channel'
       assert_broadcasts channel_name, 0

       # run your method (e.g. trasmit)
       assert_broadcasts channel_name, 1
    end
end

或验证预期的数据是否已发送到通道:

class ScannerTest < ActionDispatch::IntegrationTest
    include ActionCable::TestHelper

    def test_my_broadcaster
       channel_name = 'my_channel'
       expected_data =  :hello => "world" 
       assert_broadcast_on(channel_name, data: expected_data) do
          # run your trasmit method here which should call:
          ActionCable.server.broadcast channel_name, data: expected_data 
       end
    end
end

这个 Gem 可能很快就会成为 Rails 核心的一部分,所以它绝对值得一看,尤其是当您测试 ActionCable 的其他部分时,迟早可能会有太多工作无法模拟。 (例如,使用特定用户登录)。

【讨论】:

【参考方案2】:

我建议使用模拟(我使用mocha gem 进行模拟)来测试广播。这是一个简单的例子:

channel_name = 'my_channel'
msg_data = 'hello'

broadcast = mock
server = mock
server.expects(:broadcast).with(channel_name, data: msg_data).returns(broadcast)

ActionCable.expects(:server).returns(server)

这样,您将模拟所有 ActionCable.server 调用,但正在测试它们是否使用正确的参数调用。

【讨论】:

以上是关于如何在 minitest 中模拟和验证 ActionCable 传输?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Ruby MiniTest 之前/之后的套件

为啥我的 Minitest 测试没有并行运行?

无法在Minitest中发送请求标头

使用 CircleCI 和 Minitest 进行前端测试:测试等待页面加载的时间不够长

在最新的VScode中运行Minitest - 显示Ansi颜色代码

@controller在特定情况下的minitest是nil错误