Rails active jobs & Tests

anjosebar

Antonio J.

Posted on April 12, 2020

Rails active jobs & Tests

This week I worked with background jobs for Rails. It is useful to use Active Job when you're working with API Rest because your app needs to respond ASAP to your client's devices, i.e. web browsers, mobile apps or CLI apps in order to get a better UX. 🚀

Active Job

Active Job is a framework for declaring jobs and making them run on a variety of queuing backends. These jobs can be everything from regularly scheduled clean-ups, to billing charges, to mailings. Anything that can be chopped up into small units of work and run in parallel, really.

Let's suppose you have to update your user's information with some information from another service.

To create a job run the command
rails g job update_user

Rails will create a file called update_user_job.rb in your app/jobs folder. You can edit the file and run your needed application logic inside the perform method

# app/jobs/update_user_job.rb
class UpdateUserJob < ApplicationJob
  queue_as :default

  def perform(user_id)
    user = User.find(user_id)
    # let's imagine you're getting external information for your user
    metadata = get_some_external_metadata(user.email)
    user.update(metadata: metadata)
  end
end
Enter fullscreen mode Exit fullscreen mode

Then you need to call your job's perform_later method whenever you want to execute your job

# app/models/user.rb
  after_create :update_metadata

  def update_metadata
    UpdateUserJob.perform_later(user_id)
  end
Enter fullscreen mode Exit fullscreen mode

That's it! Let's take a look at how to test this.

Test your background job

It gets more complicated to test your background jobs because your tests will call the methods but your user fields won't be updated. Your user is being updated in the background! Thanks to Active Job Test Helper we can use some methods to test whether our jobs are being enqueued and updating our users, i.e:

  • assert_enqueued_with Asserts that the job has been enqueued with the given arguments.
  • assert_performed_jobs Asserts that the number of performed jobs matches the given number.
  • perform_enqueued_jobs Performs all enqueued jobs.
 test "update user metadata when created" do
    user = user(:one)
    assert_enqueued_with(job: UpdateUserJob, args: [user.id])
    perform_enqueued_jobs
    assert_performed_jobs 1
  end
Enter fullscreen mode Exit fullscreen mode

Rspec

If you're using rspec-rails gem, you have helpers as an alternative to help you test your background jobs. Your tests must set the queue adapter as :test ActiveJob::Base.queue_adapter = :test and you'll be able to use methods like enqueue_job and have_been_enqueued

Links:

💖 💪 🙅 🚩
anjosebar
Antonio J.

Posted on April 12, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Meta Programming Rails Test
ruby Meta Programming Rails Test

November 17, 2021

Rails active jobs & Tests
ruby Rails active jobs & Tests

April 12, 2020