ActiveJob::TestCase#perform_enqueued_jobs is used for performing all enqueued jobs in tests.
Before Rails 6
We can pass a block to perform_enqueued_jobs
and it performs all the jobs specified in the duration of the block.
perform_enqueued_jobs do
TestJob.perform_later
end
assert_enqueued_jobs 0
assert_performed_jobs 1
With Rails 6
We can use perform_enqueued_jobs
without a block also.
It will perform all the enqueued jobs.
TestJob.perform_later
MyJob.perform_later
perform_enqueued_jobs
assert_performed_jobs 2
Now the problem arises when we call perform_enqueued_jobs
multiple times
TestJob.perform_later("John")
assert_enqueued_jobs 1
assert_performed_jobs 0
perform_enqueued_jobs # It runs the job with John
assert_performed_jobs 1
TestJob.perform_later("Michael")
assert_enqueued_jobs 2
perform_enqueued_jobs # It runs the job with both John and Michael
assert_performed_jobs 3
We can see a problem that after running the job with John,
it doesn’t remove the job from the queue.
That is why the second perform_enqueued_jobs
call runs the job with both John and Michael.
Rails 6.1
Rails 6.1 has fixed
this issue and made the behavior similar to using perform_enqueued_jobs
with a block.
Let’s take the example mentioned above
TestJob.perform_later("John")
assert_enqueued_jobs 1
assert_performed_jobs 0
perform_enqueued_jobs # It runs the job with John
assert_performed_jobs 1
assert_enqueued_jobs 0
TestJob.perform_later("Michael")
assert_enqueued_jobs 1
perform_enqueued_jobs # It runs the job with Michael
assert_performed_jobs 2
assert_enqueued_jobs 0
We can see that the second perform_enqueued_jobs
call runs the job with Michael only.