Skip to content

Instantly share code, notes, and snippets.

@tomekw
Last active January 10, 2022 20:51
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save tomekw/02f4d9c8b7872da4a2bed4d8422551d7 to your computer and use it in GitHub Desktop.
Save tomekw/02f4d9c8b7872da4a2bed4d8422551d7 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
@gudongfeng
Copy link

I believe the the action value in line 47 should be say_hello instead of test_action :)

@GuilleLeopold
Copy link

Hi. I tried to use this example but the TestConnection stub is raising an error "Undefined method server for TestConnection"

@Epigene
Copy link

Epigene commented Jan 24, 2018

As @FrankGu mentioned, fixing line 47 makes the spec pass, yay!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment