From e818f65770fe115ab1cc7fbacc0e7e94d92af6a4 Mon Sep 17 00:00:00 2001 From: Michael Ryan Date: Fri, 6 Feb 2015 13:05:28 -0500 Subject: Add an `:only` option to `perform_enqueued_jobs` to filter jobs based on type. This allows specific jobs to be tested, while preventing others from being performed unnecessarily. Example: def test_hello_job assert_performed_jobs 1, only: HelloJob do HelloJob.perform_later('jeremy') LoggingJob.perform_later end end An array may also be specified, to support testing multiple jobs. Example: def test_hello_and_logging_jobs assert_nothing_raised do assert_performed_jobs 2, only: [HelloJob, LoggingJob] do HelloJob.perform_later('jeremy') LoggingJob.perform_later('stewie') RescueJob.perform_later('david') end end end Fixes #18802. Trim space and document :only option. --- .../lib/active_job/queue_adapters/test_adapter.rb | 37 ++++++++++----- activejob/lib/active_job/test_helper.rb | 55 ++++++++++++++++++++-- 2 files changed, 74 insertions(+), 18 deletions(-) (limited to 'activejob/lib') diff --git a/activejob/lib/active_job/queue_adapters/test_adapter.rb b/activejob/lib/active_job/queue_adapters/test_adapter.rb index ea9df9a063..c9e2bdca27 100644 --- a/activejob/lib/active_job/queue_adapters/test_adapter.rb +++ b/activejob/lib/active_job/queue_adapters/test_adapter.rb @@ -11,7 +11,7 @@ module ActiveJob # Rails.application.config.active_job.queue_adapter = :test class TestAdapter delegate :name, to: :class - attr_accessor(:perform_enqueued_jobs, :perform_enqueued_at_jobs) + attr_accessor(:perform_enqueued_jobs, :perform_enqueued_at_jobs, :filter) attr_writer(:enqueued_jobs, :performed_jobs) def initialize @@ -30,22 +30,33 @@ module ActiveJob end def enqueue(job) #:nodoc: - if perform_enqueued_jobs - performed_jobs << {job: job.class, args: job.serialize['arguments'], queue: job.queue_name} - Base.execute job.serialize - else - enqueued_jobs << {job: job.class, args: job.serialize['arguments'], queue: job.queue_name} - end + return if filtered?(job) + + job_data = { job: job.class, args: job.serialize['arguments'], queue: job.queue_name } + enqueue_or_perform(perform_enqueued_jobs, job, job_data) end def enqueue_at(job, timestamp) #:nodoc: - if perform_enqueued_at_jobs - performed_jobs << {job: job.class, args: job.serialize['arguments'], queue: job.queue_name, at: timestamp} - Base.execute job.serialize - else - enqueued_jobs << {job: job.class, args: job.serialize['arguments'], queue: job.queue_name, at: timestamp} - end + return if filtered?(job) + + job_data = { job: job.class, args: job.serialize['arguments'], queue: job.queue_name, at: timestamp } + enqueue_or_perform(perform_enqueued_at_jobs, job, job_data) end + + private + + def enqueue_or_perform(perform, job, job_data) + if perform + performed_jobs << job_data + Base.execute job.serialize + else + enqueued_jobs << job_data + end + end + + def filtered?(job) + filter && !Array(filter).include?(job.class) + end end end end diff --git a/activejob/lib/active_job/test_helper.rb b/activejob/lib/active_job/test_helper.rb index c544e8a10f..25bc99a4f8 100644 --- a/activejob/lib/active_job/test_helper.rb +++ b/activejob/lib/active_job/test_helper.rb @@ -125,10 +125,32 @@ module ActiveJob # HelloJob.perform_later('sean') # end # end - def assert_performed_jobs(number) + # + # The block form supports filtering. If the :only option is specified, + # then only the listed job(s) will be performed. + # + # def test_hello_job + # assert_performed_jobs 1, only: HelloJob do + # HelloJob.perform_later('jeremy') + # LoggingJob.perform_later + # end + # end + # + # An array may also be specified, to support testing multiple jobs. + # + # def test_hello_and_logging_jobs + # assert_nothing_raised do + # assert_performed_jobs 2, only: [HelloJob, LoggingJob] do + # HelloJob.perform_later('jeremy') + # LoggingJob.perform_later('stewie') + # RescueJob.perform_later('david') + # end + # end + # end + def assert_performed_jobs(number, only: nil) if block_given? original_count = performed_jobs.size - perform_enqueued_jobs { yield } + perform_enqueued_jobs(only: only) { yield } new_count = performed_jobs.size assert_equal original_count + number, new_count, "#{number} jobs expected, but #{new_count - original_count} were performed" @@ -157,11 +179,33 @@ module ActiveJob # end # end # + # The block form supports filtering. If the :only option is specified, + # then only the listed job(s) will be performed. + # + # def test_hello_job + # assert_performed_jobs 1, only: HelloJob do + # HelloJob.perform_later('jeremy') + # LoggingJob.perform_later + # end + # end + # + # An array may also be specified, to support testing multiple jobs. + # + # def test_hello_and_logging_jobs + # assert_nothing_raised do + # assert_performed_jobs 2, only: [HelloJob, LoggingJob] do + # HelloJob.perform_later('jeremy') + # LoggingJob.perform_later('stewie') + # RescueJob.perform_later('david') + # end + # end + # end + # # Note: This assertion is simply a shortcut for: # # assert_performed_jobs 0, &block - def assert_no_performed_jobs(&block) - assert_performed_jobs 0, &block + def assert_no_performed_jobs(only: nil, &block) + assert_performed_jobs 0, only: only, &block end # Asserts that the job passed in the block has been enqueued with the given arguments. @@ -206,11 +250,12 @@ module ActiveJob queue_adapter.performed_jobs = original_performed_jobs + performed_jobs end - def perform_enqueued_jobs + def perform_enqueued_jobs(only: nil) @old_perform_enqueued_jobs = queue_adapter.perform_enqueued_jobs @old_perform_enqueued_at_jobs = queue_adapter.perform_enqueued_at_jobs queue_adapter.perform_enqueued_jobs = true queue_adapter.perform_enqueued_at_jobs = true + queue_adapter.filter = only yield ensure queue_adapter.perform_enqueued_jobs = @old_perform_enqueued_jobs -- cgit v1.2.3