提交 e818f657 编写于 作者: M Michael Ryan

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.
上级 ec6c98f7
......@@ -44,5 +44,39 @@
*Isaac Seymour*
* 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.
*Michael Ryan*
Please check [4-2-stable](https://github.com/rails/rails/blob/4-2-stable/activejob/CHANGELOG.md) for previous changes.
......@@ -11,7 +11,7 @@ module QueueAdapters
# 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 @@ def performed_jobs
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
......@@ -125,10 +125,32 @@ def assert_no_enqueued_jobs(only: nil, &block)
# 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 @@ def assert_performed_jobs(number)
# 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 @@ def assert_performed_with(args = {}, &_block)
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
......
......@@ -4,6 +4,7 @@
require 'jobs/hello_job'
require 'jobs/logging_job'
require 'jobs/nested_job'
require 'jobs/rescue_job'
require 'models/person'
class EnqueuedJobsTest < ActiveJob::TestCase
......@@ -283,6 +284,83 @@ def test_assert_no_performed_jobs_failure
assert_match(/0 .* but 1/, error.message)
end
def test_assert_performed_jobs_with_only_option
assert_nothing_raised do
assert_performed_jobs 1, only: HelloJob do
HelloJob.perform_later('jeremy')
LoggingJob.perform_later
end
end
end
def test_assert_performed_jobs_with_only_option_as_array
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 test_assert_performed_jobs_with_only_option_and_none_sent
error = assert_raise ActiveSupport::TestCase::Assertion do
assert_performed_jobs 1, only: HelloJob do
LoggingJob.perform_later
end
end
assert_match(/1 .* but 0/, error.message)
end
def test_assert_performed_jobs_with_only_option_and_too_few_sent
error = assert_raise ActiveSupport::TestCase::Assertion do
assert_performed_jobs 5, only: HelloJob do
HelloJob.perform_later('jeremy')
4.times { LoggingJob.perform_later }
end
end
assert_match(/5 .* but 1/, error.message)
end
def test_assert_performed_jobs_with_only_option_and_too_many_sent
error = assert_raise ActiveSupport::TestCase::Assertion do
assert_performed_jobs 1, only: HelloJob do
2.times { HelloJob.perform_later('jeremy') }
end
end
assert_match(/1 .* but 2/, error.message)
end
def test_assert_no_performed_jobs_with_only_option
assert_nothing_raised do
assert_no_performed_jobs only: HelloJob do
LoggingJob.perform_later
end
end
end
def test_assert_no_performed_jobs_with_only_option_as_array
assert_nothing_raised do
assert_no_performed_jobs only: [HelloJob, RescueJob] do
LoggingJob.perform_later
end
end
end
def test_assert_no_performed_jobs_with_only_option_failure
error = assert_raise ActiveSupport::TestCase::Assertion do
assert_no_performed_jobs only: HelloJob do
HelloJob.perform_later('jeremy')
LoggingJob.perform_later
end
end
assert_match(/0 .* but 1/, error.message)
end
def test_assert_performed_job
assert_performed_with(job: NestedJob, queue: 'default') do
NestedJob.perform_later
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册