Ruby on rails 如何使用RSpec测试ActionCable频道?

Ruby on rails 如何使用RSpec测试ActionCable频道?,ruby-on-rails,rspec,ruby-on-rails-5,actioncable,Ruby On Rails,Rspec,Ruby On Rails 5,Actioncable,我想知道如何测试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]}&

我想知道如何测试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
class ChatChannel
subscribed
方法更新数据库并定义两个要跨频道广播的流,但细节不是很重要,因为我的问题更一般:

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

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

我将安装并配置用于录制套接字交互(“类似于WebSocket的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

您可能想等待*被合并。它添加了ActionCable::TestCase。合并后,rspec rails团队将尽其所能:

*等待是可选的;你不能等待,不能把自己的工作建立在“正在进行的工作”的基础上,然后马上找到一个可行的解决方案


您可以使用'action cable testing'gem

将此添加到您的GEM文件
gem“动作电缆测试”

然后运行
$bundle安装

然后添加以下规范

#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中的自述

rspec和测试用例都有示例,现在Rails 6包括

因此,没有必要添加宝石。你可以做任何一件事

assert_has_stream "chat_1"
或者,对于rspec:

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

这是一个非常好的主意,谢谢,但是(如果我错了,请纠正我)当您想要存根外部http请求时(例如,如果我的控制器操作发出一个外部调用),使用VCR(和TCR类似)是有意义的,但这里不是这样-这里我只想调用我自己的内部方法。但再一次,这是个好主意,我会试试。嘿,丹尼,你找到解决办法了吗?如果是这样的话,你能指出一份我可以核查的回购协议吗?嘿@SzilardMagyar,你找到解决办法了吗?