palkan / action-cable-testing

Action Cable testing utils
MIT License
213 stars 17 forks source link

undefined method `assert_nothing_raised' in gems/actioncable-6.1.1/lib/action_cable/test_helper.rb:48:in `assert_broadcasts' (Rails 6.1, Rspec 4.0.2) #85

Closed jasonfb closed 3 years ago

jasonfb commented 3 years ago
 1) CallController#create should emit RoomChannel
     Failure/Error:
       assert_broadcasts('room', 1) do
         post :create, params: {
           room_id: room.id,
           call: {
             a: 1
           }
         }
       end

     NoMethodError:
       undefined method `assert_nothing_raised' for #<RSpec::ExampleGroups::CallController::Create:0x00007fdb9866d750>
       Did you mean?  assert_routing
     # /Users/jason/.rvm/gems/ruby-2.6.3/gems/actioncable-6.1.1/lib/action_cable/test_helper.rb:48:in `assert_broadcasts'
     # ./spec/controllers/call_controller_spec.rb:23:in `block (3 levels) in <top (required)>'

Finished in 0.0991 seconds (files took 2.62 seconds to load)
2 examples, 1 failure

Failed examples:

rspec ./spec/controllers/call_controller_spec.rb:20 # CallController#create should emit RoomChannel

my spec:

require 'rails_helper'

describe CallController do
  let!(:room) {create(:room)}
  describe "#create" do
    it "should return no content" do
      post :create, params: {
        room_id: room.id,
        call: {
          a: 1
        }
      }
      expect(response).to have_http_status(:no_content)
    end

    it "should emit RoomChannel" do
      assert_broadcasts('room', 1) do
        post :create, params: {
          room_id: room.id,
          call: {
            a: 1
          }
        }
      end
    end
  end
end

my code:

class CallController < ApplicationController

  skip_forgery_protection
  before_action :load_room

  def load_room
    @room = Room.find(params[:room_id])
  end

  def create
    head :no_content
    # logger.debug("CallController# create... calling: #{call_params.inspect}")

    RoomChannel.broadcast_to(@room, call_params)
  end

  private

  def call_params
    params.require(:call).permit(:type, :from, :to, :sdp, :candida)
  end
end

All I really need to do is assert that RoomChannel receives the broadcast message to the @room. I was going to do it with the old-style allow_any_instance_of(X).to receive(:___) but people recommend against this.

Also I tried doing it with double (which seems unnecessary), so simple built-in assertions would be great

I'm not sure why this bug is coming from assert_nothing_raised inside of # /Users/jason/.rvm/gems/ruby-2.6.3/gems/actioncable-6.1.1/lib/action_cable/test_helper.rb:48:in seems odd to me.

but if this gem is in Rails anyway now may I should report directly to Rails. I'm not 100% sure what I'm looking at or if if I've done something wrong above but it seems like this should work.

jasonfb commented 3 years ago

it seems like assert_nothing_raised is inside of Minitest but I can't seem to access those inside of my Rspec suite can I? forgive me if missed something here.

palkan commented 3 years ago

AFAICS, the error comes from Rails itself: /Users/jason/.rvm/gems/ruby-2.6.3/gems/actioncable-6.1.1/lib/action_cable/test_helper.rb:48

action-cable-testing is meant for Rails < 6 and RSpec < 4; since you use Rails 6.1 and RSpec 4, you're using their implementations.

Try removing the gem, and if the error persists, please, submit an issue to Rails.

jasonfb commented 3 years ago

I think perhaps you misunderstand that for Rails 6.0 + Rails 6.1 however WITH Rspec, I think it turns out the gem is still actually live & a dependency.

my problem is indeed that I was accessing it the wrong way… https://relishapp.com/palkan/action-cable-testing/docs

For my Rails 6.1 app, when I included the gem and also add the require to the rails_helper.rb only then do I have access to have_broadcasted_to as expected

jasonfb commented 3 years ago

you're right my implementation above is wrong (obvs)

jasonfb commented 3 years ago

WORKS:

      data = {
        type: "SETUP",
        to: "1",
        from: "2",
        sdp: "S",
        candida: "1"
      }

      expect { post :create, params: {
        room_id: room.id,
        call: data
      } }.to have_broadcasted_to("room:#{room.to_gid_param}").with(data)

• do include the Gem • also add require "action_cable/testing/rspec" to rails_helper.rb