Skip to content

Instantly share code, notes, and snippets.

@ChuckJHardy
Last active March 3, 2024 20:10
Show Gist options
  • Star 89 You must be signed in to star a gist
  • Fork 25 You must be signed in to fork a gist
  • Save ChuckJHardy/10f54fc567ba3bd4d6f1 to your computer and use it in GitHub Desktop.
Save ChuckJHardy/10f54fc567ba3bd4d6f1 to your computer and use it in GitHub Desktop.
Example ActiveJob with RSpec Tests
class MyJob < ActiveJob::Base
queue_as :urgent
rescue_from(NoResultsError) do
retry_job wait: 5.minutes, queue: :default
end
def perform(*args)
MyService.call(*args)
end
end
require 'rails_helper'
RSpec.describe MyJob, type: :job do
include ActiveJob::TestHelper
subject(:job) { described_class.perform_later(123) }
it 'queues the job' do
expect { job }
.to change(ActiveJob::Base.queue_adapter.enqueued_jobs, :size).by(1)
end
it 'is in urgent queue' do
expect(MyJob.new.queue_name).to eq('urgent')
end
it 'executes perform' do
expect(MyService).to receive(:call).with(123)
perform_enqueued_jobs { job }
end
it 'handles no results error' do
allow(MyService).to receive(:call).and_raise(NoResultsError)
perform_enqueued_jobs do
expect_any_instance_of(MyJob)
.to receive(:retry_job).with(wait: 10.minutes, queue: :default)
job
end
end
after do
clear_enqueued_jobs
clear_performed_jobs
end
end
# As of RSpec 3.4.0 we now have #have_enqueued_job
# https://www.relishapp.com/rspec/rspec-rails/v/3-5/docs/matchers/have-enqueued-job-matcher
RSpec.describe MyJob, type: :job do
subject(:job) { described_class.perform_later(key) }
let(:key) { 123 }
it 'queues the job' do
expect { job }.to have_enqueued_job(described_class)
.with(key)
.on_queue("urgent")
end
end
@ChuckJHardy
Copy link
Author

Updated to include RSpec 3.4.0 #have_enqueued_job

@ollie314
Copy link

ollie314 commented Aug 8, 2017

πŸ‘

@jingz
Copy link

jingz commented Sep 6, 2017

πŸ‘

@fitchMitch
Copy link

πŸ‘

@wiskarindra
Copy link

πŸ‘

@kaka-ruto
Copy link

πŸ‘

@gogvale
Copy link

gogvale commented Sep 7, 2021

πŸ‘

@Proxima89
Copy link

πŸ‘

@mandarvaze
Copy link

Is there a way to test that retry happened after :wait period ?

@ChuckJHardy
Copy link
Author

Is there a way to test that retry happened after :wait period ?

Great question @mandarvaze! This feels like testing the internals of Rails, which I avoid to ensure I can move confidently without brittle tests. I am happy to trust that if the expected arguments are passed during the method call, the framework is doing its job as expected. If testing this is critical to your flow, maybe high-level acceptance tests are better suited. Hope this helps.

@mandarvaze
Copy link

@ChuckJHardy Thanks. It does make sense to trust the internals πŸ˜„

@chumakoff
Copy link

chumakoff commented Feb 16, 2024

subject(:job) { described_class.perform_later(123) }

it 'queues the job' 

it 'executes perform' 

Those two specs don't test your job. They test the ActiveJob's #perform_later method, wich is pointless.

This kind of test shouldn't use the perform_enqueued_jobs method at all. It's for higher level tests.

@lortza
Copy link

lortza commented Feb 26, 2024

πŸ‘

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment