RSpec for Sidekiq Pro
Installation
bundle add rspec-sidekiq_pro --group=test
Configuration
rspec/sidekiq_pro
requires sidekiq/testing
by default so there is no need to include it.
It also means that Sidekiq in set to fake
mode by default. Take a look at Sidekiq wiki for more details.
If you wish to start each spec without enqueued jobs or batches:
require "rspec/sidekiq_pro"
RSpec.configure do |config|
config.before do
Sidekiq::Queues.clear_all
RSpec::SidekiqPro::Batches.clear_all
end
end
Usage
Two matchers are provided:
-
enqueue_sidekiq_job
supports block expectation -
have_enqueued_sidekiq_job
supports value expectation
it do
expect { SampleJob.perform_async }.to enqueue_sidekiq_job(SampleJob)
end
it do
SampleJob.perform_async
expect(SampleJob).to have_enqueued_sidekiq_job
end
Both matchers provide the same chainable methods:
.with
.once
.twice
.exactly(n).times
.more_than(n).times
.less_than(n).times
.at_least(n).times
.at_most(n).times
.in
.at
.within_batch
.without_batch
Checking arguments
it do
expect { SampleJob.perform_async(1, 2, 3) }
.to enqueue_sidekiq_job(SampleJob).with(1, 2, 3)
end
it do
SampleJob.perform_async(1, 2, 3)
expect(SampleJob).to have_enqueued_sidekiq_job.with(1, 2, 3)
end
Checking counts
it do
expect { SampleJob.perform_async }
.to enqueue_sidekiq_job(SampleJob).once
end
it do
expect {
2.times { SampleJob.perform_async }
}.to enqueue_sidekiq_job(SampleJob).twice
end
it do
expect {
3.times { SampleJob.perform_async }
}.to enqueue_sidekiq_job(SampleJob).exactly(3).times
end
it do
expect {
10.times { SampleJob.perform_async }
}.to enqueue_sidekiq_job(SampleJob).more_than(5).times
end
Be careful when checking both counts and arguments:
it do
expect {
SampleJob.perform_async.with(1)
SampleJob.perform_async.with(2)
}
.to enqueue_sidekiq_job(SampleJob).twice
.and enqueue_sidekiq_job(SampleJob).once.with(1)
.and enqueue_sidekiq_job(SampleJob).once.with(2)
end
Checking schedules
it do
expect {
SampleJob.perform_in(5.minutes)
}.to enqueue_sidekiq_job(SampleJob).in(5.minutes)
end
it do
expect {
SampleJob.perform_at(10.minutes.from_now)
}.to enqueue_sidekiq_job(SampleJob).at(10.minutes.from_now)
end
Time matching is performed to the second, if you have code that takes some time to be executed consider using Timecop.
Batches
it do
expect {
SampleJob.perform_async
}.to enqueue_sidekiq_job(SampleJob).without_batch
end
it do
expect {
batch = Sidekiq::Batch.new
batch.jobs { SampleJob.perform_async }
}.to enqueue_sidekiq_job(SampleJob).within_batch
end
it do
expect { start_some_complex_workflow }
.to enqueue_sidekiq_job(SampleJob).twice.within_batch { |batch|
expect(batch).to have_attributes(description: "Complex Workflow first step")
}
end
within_batch
and without_batch
require Sidekiq::Testing
to be enabled.
When Sidekiq::Testing
is enabled, every batch is pushed to RSpec::SidekiqPro::Batches
instead of Redis.
it do
batch = Sidekiq::Batch.new
batch.jobs { SampleJob.perform_async }
expect(RSpec::SidekiqPro::Batches.first.bid).to eq(batch.bid)
end
Contributing
- Don't hesitate to submit your feature/idea/fix in issues
- Fork the repository
- Create your feature branch
- Ensure RSpec & Rubocop are passing
- Create a pull request
Tests & lint
bundle exec rspec
bundle exec rubocop
bundle exec standardrb
All of them can be run with:
bundle exec rake
License & credits
Please see LICENSE for further details.
Inspired by the philostler/rspec-sidekiq & pirj/rspec-enqueue_sidekiq_job
Contributors: ./graphs/contributors