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?

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