https://github.com/wspurgin/rspec-sidekiq
RSpec for Sidekiq
https://github.com/wspurgin/rspec-sidekiq
Keywords from Contributors
activerecord rubygems activejob mvc sidekiq rspec jobs background-jobs crash-reporting rack
Last synced: about 14 hours ago
JSON representation
Repository metadata
RSpec for Sidekiq
- Host: GitHub
- URL: https://github.com/wspurgin/rspec-sidekiq
- Owner: wspurgin
- License: other
- Created: 2013-03-23T16:27:27.000Z (almost 13 years ago)
- Default Branch: main
- Last Pushed: 2025-12-12T23:10:31.000Z (28 days ago)
- Last Synced: 2025-12-19T21:58:24.953Z (21 days ago)
- Language: Ruby
- Homepage: https://github.com/wspurgin/rspec-sidekiq
- Size: 390 KB
- Stars: 679
- Watchers: 9
- Forks: 140
- Open Issues: 5
- Releases: 20
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGES.md
- License: LICENSE
README.md
Simple testing of Sidekiq jobs via a collection of matchers and helpers.
Jump to Matchers » | Jump to Helpers »
Installation
# Gemfile
group :test do
gem 'rspec-sidekiq'
end
rspec-sidekiq requires sidekiq/testing by default so there is no need to include the line require "sidekiq/testing" inside your spec_helper.rb.
[!IMPORTANT]
This has the effect of not pushing enqueued jobs to Redis but to ajobarray to enable testing (see the FAQ & Troubleshooting Wiki page). Thus, only includegem "rspec-sidekiq"in environments where this behaviour is required, such as thetestgroup.*
Configuration
If you wish to modify the default behaviour, add the following to your spec_helper.rb file
RSpec::Sidekiq.configure do |config|
# Clears all job queues before each example
config.clear_all_enqueued_jobs = true # default => true
# Whether to use terminal colours when outputting messages
config.enable_terminal_colours = true # default => true
# Warn when jobs are not enqueued to Redis but to a job array
config.warn_when_jobs_not_processed_by_sidekiq = true # default => true
end
Matchers
enqueue_sidekiq_jobhave_enqueued_sidekiq_jobbe_processed_inbe_retryablesave_backtracebe_uniquebe_expired_inbe_delayed(deprecated)
enqueue_sidekiq_job
Describes that the block should enqueue a job. Optionally specify the
specific job class, arguments, timing, and other context
# Basic
expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job
# A specific job class
expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job(AwesomeJob)
# with specific arguments
expect { AwesomeJob.perform_async "Awesome!" }.to enqueue_sidekiq_job.with("Awesome!")
# On a specific queue
expect { AwesomeJob.set(queue: "high").perform_async }.to enqueue_sidekiq_job.on("high")
# At a specific datetime
specific_time = 1.hour.from_now
expect { AwesomeJob.perform_at(specific_time) }.to enqueue_sidekiq_job.at(specific_time)
# In a specific interval (be mindful of freezing or managing time here)
freeze_time do
expect { AwesomeJob.perform_in(1.hour) }.to enqueue_sidekiq_job.in(1.hour)
end
# A specific number of times
expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job.never
expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job.exactly(0)
expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job.exactly(0).time
expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job.once
expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job.exactly(1).time
expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job.exactly(:once)
expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job.at_least(1).time
expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job.at_least(:once)
expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job.at_most(2).times
expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job.at_most(:twice)
expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job.at_most(:thrice)
# With specific context:
# Useful for testing anything `set` on the job, including
# overrides to things like `retry`
expect {
AwesomeJob.set(trace_id: "something").perform_async
}.to enqueue_sidekiq_job.with_context(trace_id: anything)
expect {
AwesomeJob.set(retry: 5).perform_async
}.to enqueue_sidekiq_job.with_context(retry: 5)
# Combine and chain them as desired
expect { AwesomeJob.perform_at(specific_time, "Awesome!") }.to(
enqueue_sidekiq_job(AwesomeJob)
.with("Awesome!")
.on("default")
.at(specific_time)
)
# Also composable
expect do
AwesomeJob.perform_async
OtherJob.perform_async
end.to enqueue_sidekiq_job(AwesomeJob).and enqueue_sidekiq_job(OtherJob)
have_enqueued_sidekiq_job
Describes that there should be an enqueued job (with the specified arguments):
AwesomeJob.perform_async 'Awesome', true
# test with...
expect(AwesomeJob).to have_enqueued_sidekiq_job
expect(AwesomeJob).to have_enqueued_sidekiq_job('Awesome', true)
You can use the built-in RSpec args matchers too:
AwesomeJob.perform_async({"something" => "Awesome", "extra" => "stuff"})
# using built-in matchers from rspec-mocks:
expect(AwesomeJob).to have_enqueued_sidekiq_job(hash_including("something" => "Awesome"))
expect(AwesomeJob).to have_enqueued_sidekiq_job(any_args)
expect(AwesomeJob).to have_enqueued_sidekiq_job(hash_excluding("bad_stuff" => anything))
# composable as well
expect(AwesomeJob).to have_enqueued_sidekiq_job(any_args).and have_enqueued_sidekiq_job(hash_including("something" => "Awesome"))
You can specify the number of jobs enqueued:
expect(AwesomeJob).to have_enqueued_sidekiq_job.once
expect(AwesomeJob).to have_enqueued_sidekiq_job.exactly(1).time
expect(AwesomeJob).to have_enqueued_sidekiq_job.exactly(:once)
expect(AwesomeJob).to have_enqueued_sidekiq_job.at_least(1).time
expect(AwesomeJob).to have_enqueued_sidekiq_job.at_least(:once)
expect(AwesomeJob).to have_enqueued_sidekiq_job.at_most(2).times
expect(AwesomeJob).to have_enqueued_sidekiq_job.at_most(:twice)
expect(AwesomeJob).to have_enqueued_sidekiq_job.at_most(:thrice)
Likewise, specify what should be in the context:
AwesomeJob.set(trace_id: "something").perform_async
expect(AwesomeJob).to have_enqueued_sidekiq_job.with_context(trace_id: anything)
Testing scheduled jobs
Use chainable matchers #at, #in and #immediately
time = 5.minutes.from_now
AwesomeJob.perform_at time, 'Awesome', true
# test with...
expect(AwesomeJob).to have_enqueued_sidekiq_job('Awesome', true).at(time)
AwesomeJob.perform_in 5.minutes, 'Awesome', true
# test with...
expect(AwesomeJob).to have_enqueued_sidekiq_job('Awesome', true).in(5.minutes)
# Job scheduled for a date in the past are enqueued immediately.
AwesomeJob.perform_later 5.minutes.ago, 'Awesome', true # equivalent to: AwesomeJob.perform_async 'Awesome', true
# test with...
expect(AwesomeJob).to have_enqueued_sidekiq_job('Awesome', true).immediately
Testing queue set for job
Use the chainable #on matcher
class AwesomeJob
include Sidekiq::Job
sidekiq_options queue: :low
end
AwesomeJob.perform_async("a little awesome")
# test with..
expect(AwesomeJob).to have_enqueued_sidekiq_job("a little awesome").on("low")
# Setting the queue when enqueuing
AwesomeJob.set(queue: "high").perform_async("Very Awesome!")
expect(AwesomeJob).to have_enqueued_sidekiq_job("Very Awesome!").on("high")
Testing ActiveMailer jobs
user = User.first
AwesomeActionMailer.invite(user, true).deliver_later
expect(Sidekiq::Worker).to have_enqueued_sidekiq_job(
"AwesomeActionMailer",
"invite",
"deliver_now",
user,
true
)
be_processed_in
Describes the queue that a job should be processed in
sidekiq_options queue: :download
# test with...
expect(AwesomeJob).to be_processed_in :download # or
it { is_expected.to be_processed_in :download }
be_retryable
Describes if a job should retry when there is a failure in its execution
Note: this only tests against the retry option in the job's Sidekiq options.
To test an enqueued job's retry, i.e. AwesomeJob.set(retry: 5), use
with_context
sidekiq_options retry: 5
# test with...
expect(AwesomeJob).to be_retryable true # or
it { is_expected.to be_retryable true }
# ...or alternatively specify the number of times it should be retried
expect(AwesomeJob).to be_retryable 5 # or
it { is_expected.to be_retryable 5 }
# ...or when it should not retry
expect(AwesomeJob).to be_retryable false # or
it { is_expected.to be_retryable false }
save_backtrace
Describes if a job should save the error backtrace when there is a failure in its execution
sidekiq_options backtrace: 5
# test with...
expect(AwesomeJob).to save_backtrace # or
it { is_expected.to save_backtrace }
# ...or alternatively specify the number of lines that should be saved
expect(AwesomeJob).to save_backtrace 5 # or
it { is_expected.to save_backtrace 5 }
# ...or when it should not save the backtrace
expect(AwesomeJob).to_not save_backtrace # or
expect(AwesomeJob).to save_backtrace false # or
it { is_expected.to_not save_backtrace } # or
it { is_expected.to save_backtrace false }
be_unique
[!CAUTION]
This is intended to for Sidekiq Enterprise unique job implementation.
There is limited support for Sidekiq Unique Jobs, but compatibility is not
guaranteed.
Describes when a job should be unique within its queue
sidekiq_options unique_for: 1.hour
# test with...
expect(AwesomeJob).to be_unique
it { is_expected.to be_unique }
# specify a specific interval
sidekiq_options unique_for: 1.hour
it { is_expected.to be_unique.for(1.hour) }
until sub-matcher
[!CAUTION]
This sub-matcher only works for Sidekiq Enterprise
sidekiq_options unique_for: 1.hour, unique_until: :start
it { is_expected.to be_unique.until(:start) }
be_expired_in
Describes when a job should expire
sidekiq_options expires_in: 1.hour
# test with...
it { is_expected.to be_expired_in 1.hour }
it { is_expected.to_not be_expired_in 2.hours }
be_delayed
This matcher is deprecated. Use of it with Sidekiq 7+ will raise an error.
Sidekiq 7 dropped Delayed
Extensions.
Describes a method that should be invoked asynchronously (See Sidekiq Delayed Extensions)
Object.delay.is_nil? # delay
expect(Object.method :is_nil?).to be_delayed
Object.delay.is_a? Object # delay with argument
expect(Object.method :is_a?).to be_delayed(Object)
Object.delay_for(1.hour).is_nil? # delay for
expect(Object.method :is_nil?).to be_delayed.for 1.hour
Object.delay_for(1.hour).is_a? Object # delay for with argument
expect(Object.method :is_a?).to be_delayed(Object).for 1.hour
Object.delay_until(1.hour.from_now).is_nil? # delay until
expect(Object.method :is_nil?).to be_delayed.until 1.hour.from_now
Object.delay_until(1.hour.from_now).is_a? Object # delay until with argument
expect(Object.method :is_a?).to be_delayed(Object).until 1.hour.from_now
#Rails Mailer
MyMailer.delay.some_mail
expect(MyMailer.instance_method :some_mail).to be_delayed
Example matcher usage
require 'spec_helper'
describe AwesomeJob do
it { is_expected.to be_processed_in :my_queue }
it { is_expected.to be_retryable 5 }
it { is_expected.to be_unique }
it { is_expected.to be_expired_in 1.hour }
it 'enqueues another awesome job' do
subject.perform
expect(AnotherAwesomeJob).to have_enqueued_sidekiq_job('Awesome', true)
end
end
Helpers
Batches
If you are using Sidekiq Batches (Sidekiq Pro feature),
You can opt-in with stub_batches to make rspec-sidekiq mock the
implementation (using a NullObject pattern). This enables testing without a
Redis instance. Mocha and RSpec stubbing is supported here.
[!CAUTION]
Opting-in to this feature, while allowing you to test without
having Redis, does not provide the exact API thatSidekiq::Batchdoes. As
such it can cause surprises.
RSpec.describe "Using mocked batches", stub_batches: true do
it "uses mocked batches" do
batch = Sidekiq::Batch.new
batch.jobs do
SomeJob.perform_async 123
end
expect(SomeJob).to have_enqueued_sidekiq_job
# Caution, the NullObject pattern means that the mocked Batch implementation
# responds to anything... even if it's not on the true `Sidekiq::Batch` API
# For example, the following fails
expect { batch.foobar! }.to raise_error(NoMethodError)
end
end
within_sidekiq_retries_exhausted_block
sidekiq_retries_exhausted do |msg|
bar('hello')
end
# test with...
FooClass.within_sidekiq_retries_exhausted_block {
expect(FooClass).to receive(:bar).with('hello')
}
Testing
bundle exec rspec
Maintainers
Alumni
Contribute
Please do! If there's a feature missing that you'd love to see then get in on the action!
Issues/Pull Requests/Comments all welcome...
Owner metadata
- Name: Will Spurgin
- Login: wspurgin
- Email:
- Kind: user
- Description:
- Website:
- Location: Dallas, TX
- Twitter:
- Company: @stitchfix
- Icon url: https://avatars.githubusercontent.com/u/3472781?u=86797de0e1acd78da166f9100425032ea40042c2&v=4
- Repositories: 58
- Last ynced at: 2024-05-10T21:57:29.571Z
- Profile URL: https://github.com/wspurgin
GitHub Events
Total
- Create event: 6
- Release event: 2
- Issues event: 4
- Watch event: 19
- Delete event: 6
- Member event: 1
- Issue comment event: 22
- Push event: 31
- Pull request review comment event: 2
- Pull request review event: 11
- Pull request event: 49
- Fork event: 7
Last Year
- Create event: 6
- Release event: 2
- Issues event: 4
- Watch event: 12
- Delete event: 6
- Member event: 1
- Issue comment event: 21
- Push event: 30
- Pull request review event: 9
- Pull request review comment event: 2
- Pull request event: 48
- Fork event: 6
Committers metadata
Last synced: 3 days ago
Total Commits: 381
Total Committers: 66
Avg Commits per committer: 5.773
Development Distribution Score (DDS): 0.724
Commits in past year: 45
Committers in past year: 8
Avg Commits per committer in past year: 5.625
Development Distribution Score (DDS) in past year: 0.356
| Name | Commits | |
|---|---|---|
| Phil Ostler | p****r@g****m | 105 |
| Will Spurgin | w****n@s****m | 66 |
| Phil Ostler | g****b@p****m | 58 |
| Yudai Takada | t****2@g****m | 29 |
| Aidan Coyle | p****6@g****m | 16 |
| Arne De Herdt | a****e@r****m | 6 |
| Wanderson Policarpo | w****o@g****m | 6 |
| Peter M. Goldstein | p****n@g****m | 4 |
| Maarten Jacobs | m****s@d****l | 4 |
| “Pavel | “****k@b****” | 4 |
| Bernabas | b****w@w****m | 3 |
| Adam Steel | a****l@s****m | 3 |
| Arne De Herdt | a****t@g****m | 3 |
| Dominik Masur | d****r@g****m | 3 |
| Erik Ogan | e****k@o****t | 3 |
| Jesse Smith | s****y@g****m | 3 |
| Josh Becker | b****i@g****m | 3 |
| Riccardo | r****e@g****m | 3 |
| Trevor Wistaff | t****v@a****u | 2 |
| Tobias Bohwalli | hi@f****o | 2 |
| Mourad Hammiche | m****e@i****m | 2 |
| Marc Huffnagle | m****c@e****m | 2 |
| Fabio Kreusch | f****r@g****m | 2 |
| Adam Prescott | a****m@a****m | 2 |
| Adam Farhi | a****i@e****m | 2 |
| Ben Woosley and Tom Conroy | p****m@p****m | 2 |
| Brian Sharon | b****n@o****m | 2 |
| Viet Hoang | 1****g | 2 |
| dependabot[bot] | 4****] | 2 |
| Adam Farhi | y****3@g****m | 1 |
| and 36 more... | ||
Committer domains:
- stitchfix.com: 2
- pacerpro.com: 2
- philostler.com: 1
- represent.com: 1
- defacto.nl: 1
- bcgdv.com”: 1
- weddingwire.com: 1
- ogan.net: 1
- a07.com.au: 1
- futhr.io: 1
- ifeelgoods.com: 1
- element84.com: 1
- aprescott.com: 1
- ebay.com: 1
- omadahealth.com: 1
- digitalopera.com: 1
- bitwrangler.com: 1
- mac.com: 1
- sellbrite.com: 1
- stu.hosei.ac.jp: 1
- yandex.ru: 1
- chrismaximin.com: 1
- outoforder.cc: 1
- petalmd.com: 1
- shopkeep.com: 1
- runtastic.com: 1
- joshualane.com: 1
- teamnorthwoods.com: 1
Issue and Pull Request metadata
Last synced: 9 days ago
Total issues: 19
Total pull requests: 105
Average time to close issues: about 3 years
Average time to close pull requests: 3 months
Total issue authors: 18
Total pull request authors: 22
Average comments per issue: 2.47
Average comments per pull request: 0.89
Merged pull request: 59
Bot issues: 0
Bot pull requests: 2
Past year issues: 4
Past year pull requests: 63
Past year average time to close issues: 28 days
Past year average time to close pull requests: 9 days
Past year issue authors: 4
Past year pull request authors: 10
Past year average comments per issue: 0.5
Past year average comments per pull request: 0.46
Past year merged pull request: 26
Past year bot issues: 0
Past year bot pull requests: 2
Top Issue Authors
- wspurgin (2)
- pbstriker38 (1)
- r7kamura (1)
- yelled3 (1)
- nrpx (1)
- h8rry (1)
- rubendinho (1)
- n-rodriguez (1)
- mamirad (1)
- arpadlukacs (1)
- typeoneerror (1)
- IanWhitney (1)
- franzliedke (1)
- jarthod (1)
- stevecrozz (1)
Top Pull Request Authors
- ydah (44)
- wspurgin (26)
- 3v0k4 (6)
- vietqhoang (2)
- leviwilson (2)
- fynsta (2)
- jukra (2)
- ericproulx (2)
- tarellel (2)
- pboling (2)
- dependabot[bot] (2)
- monkeyWzr (2)
- guisehn (2)
- r7kamura (1)
- mochetts (1)
Top Issue Labels
- stale (3)
- new feature (2)
- question (1)
- nice-to-have (1)
Top Pull Request Labels
- dependencies (2)
- github_actions (2)
- stale (2)
Package metadata
- Total packages: 2
-
Total downloads:
- rubygems: 103,062,048 total
- Total docker downloads: 35,394,592
- Total dependent packages: 38 (may contain duplicates)
- Total dependent repositories: 1,035 (may contain duplicates)
- Total versions: 56
- Total maintainers: 1
gem.coop: rspec-sidekiq
Simple testing of Sidekiq jobs via a collection of matchers and helpers
- Homepage: http://github.com/wspurgin/rspec-sidekiq
- Documentation: http://www.rubydoc.info/gems/rspec-sidekiq/
- Licenses: MIT
- Latest release: 5.2.0 (published 6 months ago)
- Last Synced: 2026-01-06T18:12:05.295Z (3 days ago)
- Versions: 28
- Dependent Packages: 0
- Dependent Repositories: 0
- Downloads: 51,531,024 Total
- Docker Downloads: 17,697,296
-
Rankings:
- Dependent repos count: 0.0%
- Dependent packages count: 0.0%
- Average: 0.378%
- Downloads: 0.499%
- Docker downloads count: 1.015%
- Maintainers (1)
rubygems.org: rspec-sidekiq
Simple testing of Sidekiq jobs via a collection of matchers and helpers
- Homepage: http://github.com/wspurgin/rspec-sidekiq
- Documentation: http://www.rubydoc.info/gems/rspec-sidekiq/
- Licenses: MIT
- Latest release: 5.2.0 (published 6 months ago)
- Last Synced: 2026-01-06T18:52:44.282Z (3 days ago)
- Versions: 28
- Dependent Packages: 38
- Dependent Repositories: 1,035
- Downloads: 51,531,024 Total
- Docker Downloads: 17,697,296
-
Rankings:
- Downloads: 0.522%
- Dependent packages count: 0.67%
- Dependent repos count: 1.01%
- Docker downloads count: 1.118%
- Average: 1.322%
- Stargazers count: 2.291%
- Forks count: 2.323%
- Maintainers (1)
Dependencies
- actions/checkout v3 composite
- ruby/setup-ruby ee2113536afb7f793eed4ce60e8d3b26db912da4 composite
- psych >= 0
- rubinius-developer_tools >= 0
- actionmailer >= 0 development
- activejob >= 0 development
- activemodel >= 0 development
- activerecord >= 0 development
- activesupport >= 0 development
- coveralls >= 0 development
- fuubar >= 0 development
- pry >= 0 development
- pry-doc >= 0 development
- pry-nav >= 0 development
- rspec >= 0 development
- rspec-core ~> 3.0, >= 3.0.0
- sidekiq >= 2.4.0, < 7
Score: 29.46368887589563