Testing

This guide explains how to test Active Job workloads without running async-job queues inline during every test.

Testing Job Behavior

Use perform_now when testing the behavior implemented by a job. This invokes the job directly without involving a queue adapter:

class SearchIndexRefreshJobTest < ActiveJob::TestCase
	test "refreshes the product index" do
		product = products(:example)
		
		assert_changes ->{product.reload.indexed_at} do
			SearchIndexRefreshJob.perform_now(product.id)
		end
	end
end

Testing Enqueueing

Use assert_enqueued_with to verify that application code submits the expected job and arguments:

class ProductTest < ActiveSupport::TestCase
	include ActiveJob::TestHelper
	
	test "schedules an index refresh" do
		product = products(:example)
		
		assert_enqueued_with(job: SearchIndexRefreshJob, args: [product.id]) do
			product.schedule_index_refresh
		end
	end
end

Rails also provides assert_enqueued_jobs when only the number of submitted jobs matters.

Performing Enqueued Jobs

Use perform_enqueued_jobs when a test needs to exercise the code that enqueues a job and the job itself:

class ProductTest < ActiveSupport::TestCase
	include ActiveJob::TestHelper
	
	test "refreshes the index asynchronously" do
		product = products(:example)
		
		perform_enqueued_jobs do
			product.schedule_index_refresh
		end
		
		assert product.reload.indexed_at
	end
end

The helper performs jobs captured by the Rails test adapter within the block. It does not start an async-job processor or worker.

Testing Production Queue Integration

Tests using :test verify job behavior and enqueueing through Active Job, but they do not exercise the production queue transport. Cover Redis-backed definitions and separate workers with a focused integration or deployment smoke test using the same queue configuration as production.

Such a test should submit a uniquely identifiable job, wait for a worker to consume it, and verify its externally visible result. Keep this separate from the unit test suite so ordinary tests do not depend on Redis, worker timing, or another process.