palkan / action-cable-testing

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

Any ideas about using this gem with `perform_later` method? #51

Closed rbUUbr closed 5 years ago

rbUUbr commented 5 years ago

Hello! In my project I want to use perform_later method to achieve higher performance, maintainability of my sidekiq part of application. But because of perform_later is async method, inside my assignment in Rspec, I have:

      it 'broadcasts any event for user that has access' do
        expect{ subject }.to have_broadcasted_to(stream_name(user: user, object_id: 1))
      end

But this code is called asynchronously. Inside my Rails application:

  def broadcast_event_to_users_channel(event:)
    Api::V1::BroadcastUserEventJob.perform_later(user: user)
  end

And inside of my job:

module Api
  module V1
    class BroadcastUserEventJob < ApplicationJob
      queue_as :default

      def perform(user:)
        Dispatchers::UsersDispatcher.broadcast(event.to_sym,  user: user)
      end
    end
  end
end

Any ideas about using it with async things? @palkan

palkan commented 5 years ago

There are two options: 1) Test that the job has been enqueued (using have_enqueued_job matcher), i.e.:

it 'enqueues broadcast job' do
  expect{ subject }.to have_enqueued_job(Api::V1::BroadcastUserEventJob).with(user: user)
end

and test the broadcasting in the job spec:

describe Api::V1::BroadcastUserEventJob do
  subject { described_class.perform_now(user: user) }

  it "broadcasts a message" do
    expect { subject }.to have_broadcasted_to(stream_name(user: user, object_id: 1))
  end
end

2) Turn perfuming jobs on for this test (this approach doesn't care about whether the message is sent synchronously or not):

around do |ex|
  was_perform = ActiveJob::Base.queue_adapter.perform_enqueued_jobs
  ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
  ex.run
  ActiveJob::Base.queue_adapter.perform_enqueued_jobs = was_perform
end

it 'broadcasts any event for user that has access' do
  expect{ subject }.to have_broadcasted_to(stream_name(user: user, object_id: 1))
end
rbUUbr commented 5 years ago

Thanks a lot! I will close this issue