Andy Harvey
Andy Harvey

Reputation: 12653

How to test that ActiveJob is enqueued?

I have a create action that calls an ActiveJob if the record is successfully saved.

def create
  @object = Object.new(importer_params)
  respond_to do |format|
    if @object.save
      MyJob.perform_later( @object.id )
      format.html { redirect_to @object, notice: t('.notice') }
    else
      format.html { render :new }
    end
  end
end

I want to test that the Job is correctly called in a controller spec.

describe "POST #create" do
  it {
    expect {
      post :create, { object: valid_attributes }
    }.to change(Object, :count).by(1)
  }
  it { 
    expect {
      post :create, { object: valid_attributes }
    }.to have_enqueued_job(MyJob) 
  }  
end

But I get

Failure/Error:
  expect {
    post :create, { object: valid_attributes }
  }.to have_enqueued_job(MyJob)
  expected to enqueue exactly 1 jobs, but enqueued 0

The first test is passing, so I know the Object is saved successfully. What is the correct way to test that an ActiveJob is enqueued?

Upvotes: 10

Views: 20945

Answers (4)

adriannicolai
adriannicolai

Reputation: 31

we can use perform_enqueued_jobs method to wait for the jobs to finish

Upvotes: 0

Kiryl Plyashkevich
Kiryl Plyashkevich

Reputation: 2267

In official docs here is have_enqueued_job matcher

The have_enqueued_job (also aliased as enqueue_job) matcher is used to check if given ActiveJob job was enqueued.

https://relishapp.com/rspec/rspec-rails/docs/matchers/have-enqueued-job-matcher

Upvotes: 0

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230286

If you need to check that your job has been enqueued several times, you can now do this:

expect {
  3.times { HelloJob.perform_later }
}.to have_enqueued_job(HelloJob).at_least(2).times

Upvotes: 15

petecss
petecss

Reputation: 399

I've always looked at the size of ActiveJob::Base.queue_adapter.enqueued_jobs to test if a job was called. giving the code

it 'does something' do
  expect {
    post :create, { object: valid_attributes }
  }.to change {
    ActiveJob::Base.queue_adapter.enqueued_jobs.count
  }.by 1
end

You should make sure that you are setting the enqueued_jobs to an empty array after each spec to avoid any unexpected behaviour. You can do this in the spec/rails_helper.rb

Upvotes: 11

Related Questions