Testing Action Cable subscriptions in Rails

Rails provides us great a great live features in terms of Action Cable, but have you already wrote tests for your subscriptions?

Testing Action Cable subscriptions in Rails
Table of contents

Stream assertions

Let's say we have a following channel implementation that subscribes a user to a chat room:

# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
  def subscribed
    if @room = find_room
      stream_for @room
      # or
      stream_from "chat_#{params[:room_id]}"
    else
      reject
    end
  end

  private

  def find_room
    Room.find_by(id: params[:room_id])
  end
end

Then we can test this subscription implementation by writing tests subclassing ActionCable::Channel::TestCase like this:

require "test_helper"

class ChatChannelTest < ActionCable::Channel::TestCase
  setup do
    stub_connection(current_user: users(:joe))
    @room = rooms(:introductions)
  end

  test "user can join a chat room" do
    subscribe room_id: @room.id

    assert subscription.confirmed?
    assert_has_stream_for @room
    # Or
    assert_has_stream "chat_1"
  end

  test "user cannot join a non existing room" do
    subscribe room_id: -1

    assert subscription.rejected?
    assert_no_stream
  end
end

The stub_connection helper creates an Action Cable connection and subscribe subscribes to the ChatChannel . To test the subscription is successful, we can assert subscription.confirmed or subscription.rejected . To test the subscription subscribes to a specific stream, we can use assert_has_stream_for , assert_has_stream or assert_no_stream .

Author
Josef Strzibny
Hello, I am Josef and I am on Rails since its 2.0 version. I always liked strong conventions and the Rails Omakase docrine. I am author of Kamal Handbook and Test Driving Rails. I think testing should be fun, not a chore.

© Test Driving Rails Blog