rspec-rails: actioncable channel helpers not being included for rails 5.2 projects

What Ruby, Rails and RSpec versions are you using?

Ruby version: 2.7.1 Rails version: 5.2.4.3 RSpec version: rspec-rails (4.0.1)

Observed behaviour

I write a channel rspec like this:

RSpec.describe GmiChannel do
  before do
    stub_connection current_user: nil
  end
  it 'fails' do
  end
end

and it fails with

     NoMethodError:
       undefined method `stub_connection' for #<RSpec::ExampleGroups::GmiChannel::OlderRun:0x00007fa138fcd498>

Expected Behaviour

I expect stub_connection to be defined. Perhaps the version check here should allow rails 5.2:

   26:       def has_action_cable_testing?
   27          defined?(::ActionCable) && ActionCable::VERSION::MAJOR >= 6
   28        end

tl; dr section

I’ve tracked this down to a mismatch in version numbers. rspec-rails has the following method:

rspec-rails-4.0.1/lib/rspec/rails/matchers.rb:

   29: if RSpec::Rails::FeatureCheck.has_action_cable_testing?
   30    require 'rspec/rails/matchers/action_cable'
   31  end

And also,

rspec-rails-4.0.1/lib/rspec/rails/feature_check.rb:

   26:       def has_action_cable_testing?
   27          defined?(::ActionCable) && ActionCable::VERSION::MAJOR >= 6
   28        end

In my project, rails is ‘5.2.4.3’ and so actioncable is version 5.2.4.3.

Now, I’m happy to continue using action-cable-testing, but unfortunately, it detects that rspec defines " has_action_cable_testing?", issues a deprecation warning, and then doesn’t load.

Maybe I should file the bug report over there? Not sure, plus I know that he’s deprecating that gem, so starting here.

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 1
  • Comments: 15 (9 by maintainers)

Most upvoted comments

The following should work:

def has_action_cable_testing?
  defined?(::ActionCable) && (ActionCable::VERSION::MAJOR >= 6 || defined?(::ActionCable::Channel::TestCase))
end

Rails 6 setups autoload for ActionCable::Channel::TestCase, while action-cable-testing requires it on load, thus, checking for either Rails 6 version or test case class presence should be sufficient.

does Rails 5.2 have your patches to support testing channels?

Nope, Rails 5.2 has no action cable testing built-in. The action-cable-testing gem provides both Rails test classes (has been merged into Rails 6.0) and RSpec integration (has been merged into Rails 5.2). So, the gem could be used with any combination of Rails and RSpec Rails only to add the missing parts. In theory. In practice, however, it doesn’t work out-of-the-box with RSpec Rails 4, because RSpec uses versions for feature checking (and not actual feature checking).

The current workaround is to patch FeatureCheck like this:

require "action_cable/testing"
require "rspec/rails/feature_check"

RSpec::Rails::FeatureCheck.module_eval do
  module_function

  def has_action_cable_testing?
    true
  end
end

require "rspec/rails"

Should we make rspec-rails checks version-independent (see https://github.com/rspec/rspec-rails/issues/2377#issuecomment-679106872) or should we add a patch to action-cable-testing to handle this? I think, the latter one is better: feature checking is good when it works and confusing when it doesn’t (e.g., someone can add a fake ActionCable::TestCase class).

of course! just let me sleep on it and get back to you tomorrow 😉

This change is up on action-cable-flag-for-5-2 without any tests should anyone want to try it within their own suite without forking, if someone else could put together some test scenarios (in a smoke test prehaps?) that would be great.