module ActiveJob::TestHelper

def assert_performed_with(job: nil, args: nil, at: nil, queue: nil, priority: nil, &block)

end
end
MyJob.set(wait_until: Date.tomorrow.noon).perform_later
assert_performed_with(job: MyJob, at: Date.tomorrow.noon) do

end
MyJob.perform_later(1,2,3)
assert_performed_with(job: MyJob, args: [1,2,3]) do
def test_assert_performed_with

the job has been performed with the given arguments in the block.
enqueued throughout the duration of the block and asserts that
If a block is passed, that block performs all of the jobs that were

end
assert_performed_with(job: MyJob, args: args_matcher)

perform_enqueued_jobs

MyJob.perform_later(foo: "bar", other_arg: "No need to check in the test")

args_matcher = ->(job_args) { job_args[0].key?(:foo) }
def test_assert_performed_with

A proc can also be used to match a subset of a job's args:

end
assert_performed_with(job: MyJob, at: at_matcher)

perform_enqueued_jobs

MyJob.set(wait_until: Date.today.noon).perform_later

at_matcher = ->(job_at) { (Date.yesterday..Date.tomorrow).cover?(job_at) }
def test_assert_performed_with

For example, a proc can be used to match a range of times:

boolean value indicating whether a job's attribute meets certain criteria.
The given arguments may also be specified as matcher procs that return a

end
assert_performed_with(at: Date.tomorrow.noon, queue: "my_queue")

perform_enqueued_jobs

MyJob.set(wait_until: Date.tomorrow.noon, queue: "my_queue").perform_later

assert_performed_with(job: MyJob, args: [1,2,3])

perform_enqueued_jobs

MyJob.perform_later(1,2,3)
def test_assert_performed_with

Asserts that the job has been performed with the given arguments.
def assert_performed_with(job: nil, args: nil, at: nil, queue: nil, priority: nil, &block)
  require_active_job_test_adapter!("assert_performed_with")
  expected = { job: job, args: args, at: at, queue: queue, priority: priority }.compact
  expected_args = prepare_args_for_assertion(expected)
  potential_matches = []
  if block_given?
    original_performed_jobs_count = performed_jobs.count
    perform_enqueued_jobs(&block)
    jobs = performed_jobs.drop(original_performed_jobs_count)
  else
    jobs = performed_jobs
  end
  matching_job = jobs.find do |enqueued_job|
    deserialized_job = deserialize_args_for_assertion(enqueued_job)
    potential_matches << deserialized_job
    expected_args.all? do |key, value|
      if value.respond_to?(:call)
        value.call(deserialized_job[key])
      else
        value == deserialized_job[key]
      end
    end
  end
  matching_class = potential_matches.select do |enqueued_job|
    enqueued_job["job_class"] == job.to_s
  end
  message = +"No performed job found with #{expected}"
  if potential_matches.empty?
    message << "\n\nNo jobs were performed"
  elsif matching_class.empty?
    message << "\n\nNo jobs of class #{expected[:job]} were performed, job classes performed: "
    message << potential_matches.map { |job| job["job_class"] }.join(", ")
  else
    message << "\n\nPotential matches: #{matching_class.join("\n")}"
  end
  assert matching_job, message
  instantiate_job(matching_job)
end