【问题标题】:How can I test ActionCable channels using RSpec?如何使用 RSpec 测试 ActionCable 频道?
【发布时间】:2016-05-15 15:27:30
【问题描述】:

我想知道如何测试 ActionCable 频道。

假设我有以下聊天频道:

class ChatChannel < ApplicationCable::Channel
  def subscribed
    current_user.increment!(:num_of_chats)

    stream_from "chat_#{params[:chat_id]}"
    stream_from "chat_stats_#{params[:chat_id]}"
  end
end

subscribed 方法更新了数据库并定义了两个要跨频道广播的流,但细节不是很重要,因为我的问题是一个更笼统的问题:

  • 如何设置测试来测试订阅所涉及的逻辑 这个频道?

在测试控制器动作等类似交互时,RSpec 提供了许多辅助方法和各种实用程序,但我找不到有关 RSpec 和 ActionCable 的任何信息。

【问题讨论】:

    标签: ruby-on-rails rspec ruby-on-rails-5 actioncable


    【解决方案1】:

    您可能想要等待* https://github.com/rails/rails/pull/23211 被合并。它添加了 ActionCable::TestCase。一旦合并,希望 rspec-rails 团队尽自己的一份力量:https://github.com/rspec/rspec-rails/issues/1606

    * 等待是可选的;您不能等待,将自己的工作基于这个“正在进行的工作”,并找到一个现在可行的解决方案。

    【讨论】:

      【解决方案2】:

      你可以使用 `action-cable-testing` gem。

      将此添加到您的 Gemfile
      gem 'action-cable-testing'
      然后运行 ​​
      $ bundle install

      然后添加以下规范

      # spec/channels/chat_channel_spec.rb

      require "rails_helper"
      
      RSpec.describe ChatChannel, type: :channel do
        before do
          # initialize connection with identifiers
          stub_connection current_user: current_user
        end
      
        it "rejects when no room id" do
          subscribe
          expect(subscription).to be_rejected
        end
      
        it "subscribes to a stream when room id is provided" do
          subscribe(chat_id: 42)
      
          expect(subscription).to be_confirmed
          expect(streams).to include("chat_42")
          expect(streams).to include("chat_stats_42")
        end
      end
      

      有关更多信息,请参阅 github repo 中的自述文件。

      https://github.com/palkan/action-cable-testing

      rspec 和 test_case 都有例子

      【讨论】:

        【解决方案3】:

        我会安装和配置 TCR gem 以记录套接字交互('它就像 websockets 的 VCR')

        在您的情况下,此规范可能看起来像这样......

        describe ChatChannel do
          context ".subscribed" do
            it "updates db and defines opens 2 streams for one channel" do
              TCR.use_cassette("subscribed_action") do |cassette|
                # ...
                ChatChannel.subscribed
                expect(cassette).to include "something ..."
              end
            end
          end
        end
        

        【讨论】:

        • 这是一个非常好的主意,谢谢,但是(如果我错了,请纠正我)当您想要存根外部 http 请求时(例如,如果我的控制器action 发出一个外部调用),但这里不是这种情况 - 在这里我只想调用我自己的内部方法。但再一次 - 这是一个好主意,我会试一试。
        • 嗨 Dani,你找到解决方案了吗?如果是这样,你能指出一个我可以查看的回购吗?
        • 嘿@SzilardMagyar 你找到解决办法了吗?
        【解决方案4】:

        现在 Rails 6 包含 action-cable-test gem

        所以不需要添加宝石。你可以做任何一个

        assert_has_stream "chat_1"
        

        或者,使用 rspec:

        expect(subscription).to have_stream_from("chat_1") 
        

        【讨论】:

          猜你喜欢
          • 2018-08-23
          • 2018-11-06
          • 2016-08-23
          • 2019-04-12
          • 2017-12-12
          • 2018-07-07
          • 2019-04-11
          • 1970-01-01
          • 2018-07-30
          相关资源
          最近更新 更多