如何使用 RSpec 测试 ActionCable 通道?

问题描述 投票:0回答:5

我想知道如何测试 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
5个回答
8
投票

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

* 等待是可选的;您不能等待并基于此“正在进行的工作”并找到立即有效的解决方案。


7
投票

编辑: 提供的解决方案现在是 Rails 6 的一部分。您可以在不安装 gem 的情况下使用它

您可以使用

action-cable-testing
宝石。

对于轨道 < 6.0 ONLY

将其添加到您的 Gemfile 中

gem 'action-cable-testing'

然后运行
$ bundle install

适用于所有 Rails。设置规格

然后添加以下规格

# 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 存储库中的自述文件。

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

rspec 和 test_case 都有示例


3
投票

看起来它已合并到 Rails 6 中。查看发行说明 Action 电缆测试AC 测试 PR


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

3
投票

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

所以不需要添加宝石。两者都可以

assert_has_stream "chat_1"

或者,使用 rspec:

expect(subscription).to have_stream_from("chat_1") 
© www.soinside.com 2019 - 2024. All rights reserved.