Skip to content

Instantly share code, notes, and snippets.

@asccigcc
Forked from tomekw/test_channel_spec.rb
Created January 10, 2022 20:51
Show Gist options
  • Save asccigcc/6b8fb88eeb3a1cf49c4f2329d45b18eb to your computer and use it in GitHub Desktop.
Save asccigcc/6b8fb88eeb3a1cf49c4f2329d45b18eb to your computer and use it in GitHub Desktop.
Unit testing ActionCable channels with RSpec
# app/channels/hello_channel.rb
class HelloChannel < ActionCable::Channel::Base
def say_hello(data)
times_to_say_hello = data.fetch("times_to_say_hello")
hello = "Hello, #{current_profile.name}!"
times_to_say_hello.times do
ActionCable.server.broadcast(current_profile.id, hello)
end
end
end
# spec/channels/hello_channel_spec.rb
require "spec_helper"
# This is the minimal ActionCable connection stub to make the test pass
class TestConnection
attr_reader :identifiers, :logger
def initialize(identifiers_hash = {})
@identifiers = identifiers_hash.keys
@logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(StringIO.new))
# This is an equivalent of providing `identified_by :identifier_key` in ActionCable::Connection::Base subclass
identifiers_hash.each do |identifier, value|
define_singleton_method(identifier) do
value
end
end
end
end
RSpec.describe HelloChannel do
subject(:channel) { described_class.new(connection, {}) }
let(:current_profile) { double(id: "1", name: "Bob") }
# Connection is `identified_by :current_profile`
let(:connection) { TestConnection.new(current_profile: current_profile) }
let(:action_cable) { ActionCable.server }
# ActionCable dispatches actions by the `action` attribute.
# In this test we assume the payload was successfully parsed (it could be a JSON payload, for example).
let(:data) do
{
"action" => "test_action",
"times_to_say_hello" => 3
}
end
it "broadcasts 'Hello, Bob!' 3 times" do
expect(action_cable).to receive(:broadcast).with("1", "Hello, Bob!").exactly(3).times
channel.perform_action(data)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment