Module: Sidekiq::Job::ClassMethods

Defined in:
lib/sidekiq/testing.rb

Overview

The Sidekiq testing infrastructure overrides perform_async so that it does not actually touch the network. Instead it stores the asynchronous jobs in a per-class array so that their presence/absence can be asserted by your tests.

This is similar to ActionMailer's :test delivery_method and its ActionMailer::Base.deliveries array.

Example:

require 'sidekiq/testing'

assert_equal 0, HardJob.jobs.size
HardJob.perform_async(:something)
assert_equal 1, HardJob.jobs.size
assert_equal :something, HardJob.jobs[0]['args'][0]

assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
MyMailer.delay.send_welcome_email('foo@example.com')
assert_equal 1, Sidekiq::Extensions::DelayedMailer.jobs.size

You can also clear and drain all job types:

assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
assert_equal 0, Sidekiq::Extensions::DelayedModel.jobs.size

MyMailer.delay.send_welcome_email('foo@example.com')
MyModel.delay.do_something_hard

assert_equal 1, Sidekiq::Extensions::DelayedMailer.jobs.size
assert_equal 1, Sidekiq::Extensions::DelayedModel.jobs.size

Sidekiq::Worker.clear_all # or .drain_all

assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
assert_equal 0, Sidekiq::Extensions::DelayedModel.jobs.size

This can be useful to make sure jobs don't linger between tests:

RSpec.configure do |config|
  config.before(:each) do
    Sidekiq::Job.clear_all
  end
end

or for acceptance testing, i.e. with cucumber:

AfterStep do
  Sidekiq::Job.drain_all
end

When I sign up as "foo@example.com"
Then I should receive a welcome email to "foo@example.com"

Instance Method Summary collapse

Instance Method Details

#clearObject

Clear all jobs for this worker



270
271
272
# File 'lib/sidekiq/testing.rb', line 270

def clear
  Queues.clear_for(queue, to_s)
end

#drainObject

Drain and run all jobs for this worker



275
276
277
278
279
280
281
# File 'lib/sidekiq/testing.rb', line 275

def drain
  while jobs.any?
    next_job = jobs.first
    Queues.delete_for(next_job["jid"], next_job["queue"], to_s)
    process_job(next_job)
  end
end

#execute_job(worker, args) ⇒ Object



300
301
302
# File 'lib/sidekiq/testing.rb', line 300

def execute_job(worker, args)
  worker.perform(*args)
end

#jobsObject

Jobs queued for this worker



265
266
267
# File 'lib/sidekiq/testing.rb', line 265

def jobs
  Queues.jobs_by_class[to_s]
end

#perform_oneObject

Pop out a single job and perform it

Raises:



284
285
286
287
288
289
# File 'lib/sidekiq/testing.rb', line 284

def perform_one
  raise(EmptyQueueError, "perform_one called with empty job queue") if jobs.empty?
  next_job = jobs.first
  Queues.delete_for(next_job["jid"], queue, to_s)
  process_job(next_job)
end

#process_job(job) ⇒ Object



291
292
293
294
295
296
297
298
# File 'lib/sidekiq/testing.rb', line 291

def process_job(job)
  inst = new
  inst.jid = job["jid"]
  inst.bid = job["bid"] if inst.respond_to?(:bid=)
  Sidekiq::Testing.server_middleware.invoke(inst, job, job["queue"]) do
    execute_job(inst, job["args"])
  end
end

#queueObject

Queue for this worker



260
261
262
# File 'lib/sidekiq/testing.rb', line 260

def queue
  get_sidekiq_options["queue"]
end