'Execute pending job with ActiveJob in rspec

I have this code to test ActiveJob and ActionMailer with Rspec I don't know how really execute all enqueued job

describe 'whatever' do
  include ActiveJob::TestHelper

  after do
    clear_enqueued_jobs
  end  

  it 'should email' do
    expect(enqueued_jobs.size).to eq(1)
  end
end


Solution 1:[1]

Here is how I solved a similar problem:

# rails_helper.rb
RSpec.configure do |config|
  config.before :example, perform_enqueued: true do
    @old_perform_enqueued_jobs = ActiveJob::Base.queue_adapter.perform_enqueued_jobs
    @old_perform_enqueued_at_jobs = ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs
    ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
    ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs = true
  end

  config.after :example, perform_enqueued: true do
    ActiveJob::Base.queue_adapter.perform_enqueued_jobs = @old_perform_enqueued_jobs
    ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs = @old_perform_enqueued_at_jobs
  end
end

Then in specs we can use:

it "should perform immediately", perform_enqueued: true do
  SomeJob.perform_later  
end

Solution 2:[2]

The proper way to test will be to check number of enqueued jobs as in your example, and then test each job separately. If you want to do integration testing you can try perform_enqueued_jobs helper:

describe 'whatever' do
  include ActiveJob::TestHelper

  after do
    clear_enqueued_jobs
  end  

  it 'should email' do
    perform_enqueued_jobs do
      SomeClass.some_action
    end
  end
end

See ActiveJob::TestHelper docs

Solution 3:[3]

Just combined all the best pieces, +included sidekiq:

spec/support/perform_jobs.rb:

require 'sidekiq/testing'

RSpec.configure do |config|
  Sidekiq::Testing.fake!

  config.around(:each, perform_jobs: true) do |example|
    Sidekiq::Testing.inline! do
      queue_adapter = ActiveJob::Base.queue_adapter
      old_perform_enqueued_jobs = queue_adapter.perform_enqueued_jobs
      old_perform_enqueued_at_jobs = queue_adapter.perform_enqueued_at_jobs
      queue_adapter.perform_enqueued_jobs = true
      queue_adapter.perform_enqueued_at_jobs = true
      example.run
    ensure
      queue_adapter.perform_enqueued_jobs = old_perform_enqueued_jobs
      queue_adapter.perform_enqueued_at_jobs = old_perform_enqueued_at_jobs
    end
  end

end

spec/some_spec.rb:

it 'works', perform_jobs: true do
  ...
end

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Rani Kheir
Solution 2 Rimian
Solution 3 Lev Lukomsky