未验证 提交 2b594b06 编写于 作者: J Jeremy Daer 提交者: GitHub

Merge pull request #33635 from bogdanvlviv/improve-active_job-test_helpers

Improve Active Job test helpers
* Allow `assert_performed_with` to be called without a block.
*bogdanvlviv*
* Execution of `assert_performed_jobs`, and `assert_no_performed_jobs`
without a block should respect passed `:except`, `:only`, and `:queue` options.
*bogdanvlviv*
* Allow `:queue` option to job assertions and helpers.
*bogdanvlviv*
* Allow `perform_enqueued_jobs` to be called without a block. * Allow `perform_enqueued_jobs` to be called without a block.
Performs all of the jobs that have been enqueued up to this point in the test. Performs all of the jobs that have been enqueued up to this point in the test.
...@@ -11,19 +24,6 @@ ...@@ -11,19 +24,6 @@
*Zach Kemp* *Zach Kemp*
* Allow `queue` option to `assert_no_enqueued_jobs`.
Example:
```
def test_no_logging
assert_no_enqueued_jobs queue: 'default' do
LoggingJob.set(queue: :some_queue).perform_later
end
end
```
*bogdanvlviv*
* Allow call `assert_enqueued_with` with no block. * Allow call `assert_enqueued_with` with no block.
Example: Example:
......
...@@ -12,7 +12,7 @@ module QueueAdapters ...@@ -12,7 +12,7 @@ module QueueAdapters
# #
# Rails.application.config.active_job.queue_adapter = :test # Rails.application.config.active_job.queue_adapter = :test
class TestAdapter class TestAdapter
attr_accessor(:perform_enqueued_jobs, :perform_enqueued_at_jobs, :filter, :reject) attr_accessor(:perform_enqueued_jobs, :perform_enqueued_at_jobs, :filter, :reject, :queue)
attr_writer(:enqueued_jobs, :performed_jobs) attr_writer(:enqueued_jobs, :performed_jobs)
# Provides a store of all the enqueued jobs with the TestAdapter so you can check them. # Provides a store of all the enqueued jobs with the TestAdapter so you can check them.
...@@ -54,12 +54,20 @@ def perform_or_enqueue(perform, job, job_data) ...@@ -54,12 +54,20 @@ def perform_or_enqueue(perform, job, job_data)
end end
def filtered?(job) def filtered?(job)
filtered_queue?(job) || filtered_job_class?(job)
end
def filtered_queue?(job)
if queue
job.queue_name != queue.to_s
end
end
def filtered_job_class?(job)
if filter if filter
!Array(filter).include?(job.class) !Array(filter).include?(job.class)
elsif reject elsif reject
Array(reject).include?(job.class) Array(reject).include?(job.class)
else
false
end end
end end
end end
......
...@@ -52,7 +52,7 @@ def after_teardown # :nodoc: ...@@ -52,7 +52,7 @@ def after_teardown # :nodoc:
queue_adapter_changed_jobs.each { |klass| klass.disable_test_adapter } queue_adapter_changed_jobs.each { |klass| klass.disable_test_adapter }
end end
# Specifies the queue adapter to use with all active job test helpers. # Specifies the queue adapter to use with all Active Job test helpers.
# #
# Returns an instance of the queue adapter and defaults to # Returns an instance of the queue adapter and defaults to
# <tt>ActiveJob::QueueAdapters::TestAdapter</tt>. # <tt>ActiveJob::QueueAdapters::TestAdapter</tt>.
...@@ -118,13 +118,17 @@ def queue_adapter_for_test ...@@ -118,13 +118,17 @@ def queue_adapter_for_test
def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil) def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil)
if block_given? if block_given?
original_count = enqueued_jobs_with(only: only, except: except, queue: queue) original_count = enqueued_jobs_with(only: only, except: except, queue: queue)
yield yield
new_count = enqueued_jobs_with(only: only, except: except, queue: queue) new_count = enqueued_jobs_with(only: only, except: except, queue: queue)
assert_equal number, new_count - original_count, "#{number} jobs expected, but #{new_count - original_count} were enqueued"
actual_count = new_count - original_count
else else
actual_count = enqueued_jobs_with(only: only, except: except, queue: queue) actual_count = enqueued_jobs_with(only: only, except: except, queue: queue)
assert_equal number, actual_count, "#{number} jobs expected, but #{actual_count} were enqueued"
end end
assert_equal number, actual_count, "#{number} jobs expected, but #{actual_count} were enqueued"
end end
# Asserts that no jobs have been enqueued. # Asserts that no jobs have been enqueued.
...@@ -176,7 +180,7 @@ def assert_no_enqueued_jobs(only: nil, except: nil, queue: nil, &block) ...@@ -176,7 +180,7 @@ def assert_no_enqueued_jobs(only: nil, except: nil, queue: nil, &block)
# Asserts that the number of performed jobs matches the given number. # Asserts that the number of performed jobs matches the given number.
# If no block is passed, <tt>perform_enqueued_jobs</tt> # If no block is passed, <tt>perform_enqueued_jobs</tt>
# must be called around the job call. # must be called around or after the job call.
# #
# def test_jobs # def test_jobs
# assert_performed_jobs 0 # assert_performed_jobs 0
...@@ -186,11 +190,12 @@ def assert_no_enqueued_jobs(only: nil, except: nil, queue: nil, &block) ...@@ -186,11 +190,12 @@ def assert_no_enqueued_jobs(only: nil, except: nil, queue: nil, &block)
# end # end
# assert_performed_jobs 1 # assert_performed_jobs 1
# #
# perform_enqueued_jobs do
# HelloJob.perform_later('yves') # HelloJob.perform_later('yves')
#
# perform_enqueued_jobs
#
# assert_performed_jobs 2 # assert_performed_jobs 2
# end # end
# end
# #
# If a block is passed, that block should cause the specified number of # If a block is passed, that block should cause the specified number of
# jobs to be performed. # jobs to be performed.
...@@ -206,7 +211,7 @@ def assert_no_enqueued_jobs(only: nil, except: nil, queue: nil, &block) ...@@ -206,7 +211,7 @@ def assert_no_enqueued_jobs(only: nil, except: nil, queue: nil, &block)
# end # end
# end # end
# #
# The block form supports filtering. If the :only option is specified, # This method also supports filtering. If the +:only+ option is specified,
# then only the listed job(s) will be performed. # then only the listed job(s) will be performed.
# #
# def test_hello_job # def test_hello_job
...@@ -216,7 +221,7 @@ def assert_no_enqueued_jobs(only: nil, except: nil, queue: nil, &block) ...@@ -216,7 +221,7 @@ def assert_no_enqueued_jobs(only: nil, except: nil, queue: nil, &block)
# end # end
# end # end
# #
# Also if the :except option is specified, # Also if the +:except+ option is specified,
# then the job(s) except specific class will be performed. # then the job(s) except specific class will be performed.
# #
# def test_hello_job # def test_hello_job
...@@ -237,17 +242,30 @@ def assert_no_enqueued_jobs(only: nil, except: nil, queue: nil, &block) ...@@ -237,17 +242,30 @@ def assert_no_enqueued_jobs(only: nil, except: nil, queue: nil, &block)
# end # end
# end # end
# end # end
def assert_performed_jobs(number, only: nil, except: nil) #
# If the +:queue+ option is specified,
# then only the job(s) enqueued to a specific queue will be performed.
#
# def test_assert_performed_jobs_with_queue_option
# assert_performed_jobs 1, queue: :some_queue do
# HelloJob.set(queue: :some_queue).perform_later("jeremy")
# HelloJob.set(queue: :other_queue).perform_later("bogdan")
# end
# end
def assert_performed_jobs(number, only: nil, except: nil, queue: nil, &block)
if block_given? if block_given?
original_count = performed_jobs.size original_count = performed_jobs.size
perform_enqueued_jobs(only: only, except: except) { yield }
perform_enqueued_jobs(only: only, except: except, queue: queue, &block)
new_count = performed_jobs.size new_count = performed_jobs.size
assert_equal number, new_count - original_count,
"#{number} jobs expected, but #{new_count - original_count} were performed" performed_jobs_size = new_count - original_count
else else
performed_jobs_size = performed_jobs.size performed_jobs_size = performed_jobs_with(only: only, except: except, queue: queue)
assert_equal number, performed_jobs_size, "#{number} jobs expected, but #{performed_jobs_size} were performed"
end end
assert_equal number, performed_jobs_size, "#{number} jobs expected, but #{performed_jobs_size} were performed"
end end
# Asserts that no jobs have been performed. # Asserts that no jobs have been performed.
...@@ -269,7 +287,7 @@ def assert_performed_jobs(number, only: nil, except: nil) ...@@ -269,7 +287,7 @@ def assert_performed_jobs(number, only: nil, except: nil)
# end # end
# end # end
# #
# The block form supports filtering. If the :only option is specified, # The block form supports filtering. If the +:only+ option is specified,
# then only the listed job(s) will not be performed. # then only the listed job(s) will not be performed.
# #
# def test_no_logging # def test_no_logging
...@@ -278,7 +296,7 @@ def assert_performed_jobs(number, only: nil, except: nil) ...@@ -278,7 +296,7 @@ def assert_performed_jobs(number, only: nil, except: nil)
# end # end
# end # end
# #
# Also if the :except option is specified, # Also if the +:except+ option is specified,
# then the job(s) except specific class will not be performed. # then the job(s) except specific class will not be performed.
# #
# def test_no_logging # def test_no_logging
...@@ -287,11 +305,20 @@ def assert_performed_jobs(number, only: nil, except: nil) ...@@ -287,11 +305,20 @@ def assert_performed_jobs(number, only: nil, except: nil)
# end # end
# end # end
# #
# If the +:queue+ option is specified,
# then only the job(s) enqueued to a specific queue will not be performed.
#
# def test_assert_no_performed_jobs_with_queue_option
# assert_no_performed_jobs queue: :some_queue do
# HelloJob.set(queue: :other_queue).perform_later("jeremy")
# end
# end
#
# Note: This assertion is simply a shortcut for: # Note: This assertion is simply a shortcut for:
# #
# assert_performed_jobs 0, &block # assert_performed_jobs 0, &block
def assert_no_performed_jobs(only: nil, except: nil, &block) def assert_no_performed_jobs(only: nil, except: nil, queue: nil, &block)
assert_performed_jobs 0, only: only, except: except, &block assert_performed_jobs 0, only: only, except: except, queue: queue, &block
end end
# Asserts that the job has been enqueued with the given arguments. # Asserts that the job has been enqueued with the given arguments.
...@@ -338,7 +365,25 @@ def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil) ...@@ -338,7 +365,25 @@ def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil)
instantiate_job(matching_job) instantiate_job(matching_job)
end end
# Asserts that the job passed in the block has been performed with the given arguments. # Asserts that the job has been performed with the given arguments.
#
# def test_assert_performed_with
# MyJob.perform_later(1,2,3)
#
# perform_enqueued_jobs
#
# assert_performed_with(job: MyJob, args: [1,2,3], queue: 'high')
#
# MyJob.set(wait_until: Date.tomorrow.noon).perform_later
#
# perform_enqueued_jobs
#
# assert_performed_with(job: MyJob, at: Date.tomorrow.noon)
# end
#
# If a block is passed, that block performs all of the jobs that were
# enqueued throughout the duration of the block and asserts that
# the job has been performed with the given arguments in the block.
# #
# def test_assert_performed_with # def test_assert_performed_with
# assert_performed_with(job: MyJob, args: [1,2,3], queue: 'high') do # assert_performed_with(job: MyJob, args: [1,2,3], queue: 'high') do
...@@ -349,15 +394,24 @@ def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil) ...@@ -349,15 +394,24 @@ def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil)
# MyJob.set(wait_until: Date.tomorrow.noon).perform_later # MyJob.set(wait_until: Date.tomorrow.noon).perform_later
# end # end
# end # end
def assert_performed_with(job: nil, args: nil, at: nil, queue: nil) def assert_performed_with(job: nil, args: nil, at: nil, queue: nil, &block)
original_performed_jobs_count = performed_jobs.count
expected = { job: job, args: args, at: at, queue: queue }.compact expected = { job: job, args: args, at: at, queue: queue }.compact
serialized_args = serialize_args_for_assertion(expected) serialized_args = serialize_args_for_assertion(expected)
perform_enqueued_jobs { yield }
in_block_jobs = performed_jobs.drop(original_performed_jobs_count) if block_given?
matching_job = in_block_jobs.find do |in_block_job| original_performed_jobs_count = performed_jobs.count
serialized_args.all? { |key, value| value == in_block_job[key] }
perform_enqueued_jobs(&block)
jobs = performed_jobs.drop(original_performed_jobs_count)
else
jobs = performed_jobs
end
matching_job = jobs.find do |performed_job|
serialized_args.all? { |key, value| value == performed_job[key] }
end end
assert matching_job, "No performed job found with #{expected}" assert matching_job, "No performed job found with #{expected}"
instantiate_job(matching_job) instantiate_job(matching_job)
end end
...@@ -403,25 +457,42 @@ def assert_performed_with(job: nil, args: nil, at: nil, queue: nil) ...@@ -403,25 +457,42 @@ def assert_performed_with(job: nil, args: nil, at: nil, queue: nil)
# assert_performed_jobs 1 # assert_performed_jobs 1
# end # end
# #
def perform_enqueued_jobs(only: nil, except: nil) # If the +:queue+ option is specified,
# then only the job(s) enqueued to a specific queue will be performed.
#
# def test_perform_enqueued_jobs_with_queue
# perform_enqueued_jobs queue: :some_queue do
# MyJob.set(queue: :some_queue).perform_later(1, 2, 3) # will be performed
# HelloJob.set(queue: :other_queue).perform_later(1, 2, 3) # will not be performed
# end
# assert_performed_jobs 1
# end
#
def perform_enqueued_jobs(only: nil, except: nil, queue: nil)
return flush_enqueued_jobs(only: only, except: except, queue: queue) unless block_given?
validate_option(only: only, except: except) validate_option(only: only, except: except)
old_perform_enqueued_jobs = queue_adapter.perform_enqueued_jobs old_perform_enqueued_jobs = queue_adapter.perform_enqueued_jobs
old_perform_enqueued_at_jobs = queue_adapter.perform_enqueued_at_jobs old_perform_enqueued_at_jobs = queue_adapter.perform_enqueued_at_jobs
old_filter = queue_adapter.filter old_filter = queue_adapter.filter
old_reject = queue_adapter.reject old_reject = queue_adapter.reject
old_queue = queue_adapter.queue
begin begin
queue_adapter.perform_enqueued_jobs = true queue_adapter.perform_enqueued_jobs = true
queue_adapter.perform_enqueued_at_jobs = true queue_adapter.perform_enqueued_at_jobs = true
queue_adapter.filter = only queue_adapter.filter = only
queue_adapter.reject = except queue_adapter.reject = except
queue_adapter.queue = queue
block_given? ? yield : flush_enqueued_jobs(only: only, except: except) yield
ensure ensure
queue_adapter.perform_enqueued_jobs = old_perform_enqueued_jobs queue_adapter.perform_enqueued_jobs = old_perform_enqueued_jobs
queue_adapter.perform_enqueued_at_jobs = old_perform_enqueued_at_jobs queue_adapter.perform_enqueued_at_jobs = old_perform_enqueued_at_jobs
queue_adapter.filter = old_filter queue_adapter.filter = old_filter
queue_adapter.reject = old_reject queue_adapter.reject = old_reject
queue_adapter.queue = old_queue
end end
end end
...@@ -443,10 +514,10 @@ def clear_performed_jobs ...@@ -443,10 +514,10 @@ def clear_performed_jobs
performed_jobs.clear performed_jobs.clear
end end
def enqueued_jobs_with(only: nil, except: nil, queue: nil) def jobs_with(jobs, only: nil, except: nil, queue: nil)
validate_option(only: only, except: except) validate_option(only: only, except: except)
enqueued_jobs.count do |job| jobs.count do |job|
job_class = job.fetch(:job) job_class = job.fetch(:job)
if only if only
...@@ -454,17 +525,27 @@ def enqueued_jobs_with(only: nil, except: nil, queue: nil) ...@@ -454,17 +525,27 @@ def enqueued_jobs_with(only: nil, except: nil, queue: nil)
elsif except elsif except
next false if Array(except).include?(job_class) next false if Array(except).include?(job_class)
end end
if queue if queue
next false unless queue.to_s == job.fetch(:queue, job_class.queue_name) next false unless queue.to_s == job.fetch(:queue, job_class.queue_name)
end end
yield job if block_given? yield job if block_given?
true true
end end
end end
def flush_enqueued_jobs(only: nil, except: nil) def enqueued_jobs_with(only: nil, except: nil, queue: nil, &block)
enqueued_jobs_with(only: only, except: except) do |payload| jobs_with(enqueued_jobs, only: only, except: except, queue: queue, &block)
end
def performed_jobs_with(only: nil, except: nil, queue: nil, &block)
jobs_with(performed_jobs, only: only, except: except, queue: queue, &block)
end
def flush_enqueued_jobs(only: nil, except: nil, queue: nil)
enqueued_jobs_with(only: only, except: except, queue: queue) do |payload|
args = ActiveJob::Arguments.deserialize(payload[:args]) args = ActiveJob::Arguments.deserialize(payload[:args])
instantiate_job(payload.merge(args: args)).perform_now instantiate_job(payload.merge(args: args)).perform_now
queue_adapter.performed_jobs << payload queue_adapter.performed_jobs << payload
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册