如何使用 RSpec 测试 ActionCable 频道?
Posted
技术标签:
【中文标题】如何使用 RSpec 测试 ActionCable 频道?【英文标题】:How can I test ActionCable channels using RSpec? 【发布时间】: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 的任何信息。
【问题讨论】:
【参考方案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")
【讨论】:
以上是关于如何使用 RSpec 测试 ActionCable 频道?的主要内容,如果未能解决你的问题,请参考以下文章