Running ActiveJob inline in feature specs in Rails 5.2

How do you run Rails ActiveJob jobs inline when writing feature specs? Turns out that there is a neat solution


May 19, 2018 - 1 min read
ruby on railstesting

I recently wanted to add some feature specs to an existing Rails 5.2 application and ran into a little snag when using Capybara to click around on the page.

My application uses ActiveJob with Sidekiq for background jobs. By default these use the test adapter in the test environment. This means that the jobs will not execute when running tests but rather be collected in a way that you can then run assertions on, much like how ActionMailer works in test mode.

This is great for test performance and whatnot but no so great when you run feature tests and you want the test to run the application “for real”.

Here is the scenario written using Capybara and RSpec:

require "spec_helper"

feature "Movie Search", :js, :feature do
  scenario "User searches for a movie" do
    visit movie_searches_path

    within('.main') do
      first("input").set('alien').native.send_keys(:return)

      expect(page).to have_text('1979')
      expect(page).to have_text('During')

      first('button').click

      expect(page).to have_current_path(movie_waitlists_path)
      expect(page).to have_text('alien')
    end

  end
end

The scenario above will visit the movie search page, search for the movie alien, queue it for downloading and then assert that the user is redirected to the movie page that will display the details of the download.

The problem was the highlighted line. When the download is initiated the application enqueues a job for fetching the details of the movie in the background and then it will automatically update the page once the job is finished. Because the jobs were not executing in test mode this never happened and the scenario failed.

Turns out that there is a very simple solution to this issue using the ActiveJob Test Helper from Rails itself. Here is the working scenario with the changes highlighted:

require "spec_helper"

feature "Movie Search", :js, :feature do
  include ActiveJob::TestHelper

  scenario "User searches for a movie" do
    visit movie_searches_path

    within('.main') do
      first("input").set('alien').native.send_keys(:return)

      expect(page).to have_text('1979')
      expect(page).to have_text('During')

      perform_enqueued_jobs do
        first('button').click
      end

      expect(page).to have_current_path(movie_waitlists_path)
      expect(page).to have_text('alien')
    end

  end
end

Now it works properly. Neat!

Discuss on Twitter