The :test adapter doesn't respect limits_concurrency configuration. Switch to :solid_queue adapter in your test to verify blocking behavior.
Job Configuration
class MembershipJob < ApplicationJob
limits_concurrency(key: ->(membership) { membership })
end
The problem
When using the default test mode for enqueuing jobs, both will be enqueued immediately. However, we actually we want to test that only one of both will be enqueued as the other should have been blocked.
# This doesn't actually test concurrency control
test('enqueues both jobs') do
MembershipJob.perform_later(membership)
MembershipJob.perform_later(membership)
assert_enqueued_jobs(2, only: MembershipJob)
# Both enqueue, but we haven't proven the second will block
end
The solution
The solution is to use the actual solid queue adapter and query for the blocked jobs and the ones ready for execution.
test('limits concurrency second job with same membership is blocked') do
membership = create_valid_membership(id: 76381)
ActiveJob::Base.queue_adapter = :solid_queue
begin
MembershipJob.perform_later(membership)
second_blocked_job = MembershipJob.perform_later(membership)
# Verify blocking behavior
assert_equal(1, SolidQueue::ReadyExecution.count)
assert_equal(1, SolidQueue::BlockedExecution.count)
blocked = SolidQueue::BlockedExecution.last
assert_equal(second_blocked_job.provider_job_id, blocked.job_id)
ensure
ActiveJob::Base.queue_adapter = :test # Correctly restore the test adapter
end
end
Restore the Adapter
Always restore
:testadapter in theensureblock.
Further reading
Posted by Felix Eschey to makandra dev (2025-12-10 15:52)