'How can I test ActionCable channels using RSpec?
I am wondering how to test ActionCable channels.
Let's say I have the following chat channel:
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
The subscribed method updates the db and defines two streams to be broadcasted across the channel, but the details are not very important since my question is a more general one:
- How can I set up a test to test the logic involved by subscribing to this channel?
RSpec provides a lot of helper methods and various utilities when testing similar interactions like controller actions, but I couldn't find anything regarding RSpec and ActionCable.
Solution 1:[1]
You can use `action-cable-testing` gem.
Add this to your Gemfile gem 'action-cable-testing'
Then run $ bundle install
Then add following spec
# 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
For more information see readme in github repo.
https://github.com/palkan/action-cable-testing
There are examples for both rspec and test_case
Solution 2:[2]
I would install and configure TCR gem for recording sockets interaction ('its like VCR for websockets')
A spec for this in your case might look something like this...
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
Solution 3:[3]
Now Rails 6 includes the action-cable-test gem
So there is no need to add a gem. You can do either
assert_has_stream "chat_1"
or, with rspec:
expect(subscription).to have_stream_from("chat_1")
Solution 4:[4]
Look like it was merged to Rails 6. Checkout the release note Action cable testing and the pr AC testing PR
Solution 5:[5]
The example you've got is for implementing this from a list view I believe. I've updated it below to be a fairly straightforward invocable method. I'm sure you've figured it out by now, but for anyone else looking!
public class UserManagementController {
//Use method with extreme caution. Data can't be recovered.
@InvocableMethod(label='User Management' description='Obfuscate User data and more')
static public void obfuscate(List<Id> ids)
{
for (Id id : ids) {
System.UserManagement.obfuscateUser(id);
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | MilesStanfield |
| Solution 3 | Tabare |
| Solution 4 | |
| Solution 5 | João Dias |
