Skip to content

Commit

Permalink
Merge pull request #193 from wspurgin/switch-batch-mock-to-opt-in
Browse files Browse the repository at this point in the history
Update Batches mocking to be opt-in
  • Loading branch information
wspurgin authored Jul 24, 2023
2 parents e62a9cd + 1ab1276 commit 0863fb8
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 8 deletions.
35 changes: 31 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ expect(AwesomeJob).to have_enqueued_job('Awesome', true)

```ruby
time = 5.minutes.from_now
Awesomejob.perform_at time, 'Awesome', true
AwesomeJob.perform_at time, 'Awesome', true
# test with...
expect(AwesomeJob).to have_enqueued_sidekiq_job('Awesome', true).at(time)
```
```ruby
Awesomejob.perform_in 5.minutes, 'Awesome', true
AwesomeJob.perform_in 5.minutes, 'Awesome', true
# test with...
expect(AwesomeJob).to have_enqueued_sidekiq_job('Awesome', true).in(5.minutes)
```
Expand Down Expand Up @@ -196,11 +196,38 @@ end
```

## Helpers
* [Batches (Sidekiq Pro)](#batches)
* [Batches (Sidekiq Pro) _experimental_](#batches)
* [`within_sidekiq_retries_exhausted_block`](#within_sidekiq_retries_exhausted_block)

### Batches
If you are using Sidekiq Batches ([Sidekiq Pro feature][sidekiq_wiki_batches]), rspec-sidekiq replaces the implementation (using the NullObject pattern) enabling testing without a Redis instance. Mocha and RSpec stubbing is supported here.

If you are using Sidekiq Batches ([Sidekiq Pro feature][sidekiq_wiki_batches]),
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.

:warning: **Caution**: Opting-in to this feature, while allowing you to test without
having Redis, _does not_ provide the exact API that `Sidekiq::Batch` does. As
such it can cause surprises.


```ruby
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
```ruby
Expand Down
22 changes: 20 additions & 2 deletions lib/rspec/sidekiq/batch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@ def method_missing(*args, &block)
end
end

##
# Sidekiq::Batch is a Sidekiq::Pro feature. However the general consensus is
# that, by defeault, you can't test without redis. RSpec::Sidekiq includes
# a "null object" pattern implementation to mock Batches. This will mock
# Sidekiq::Batch and prevent it from using Redis.
#
# This is _opt-in_ only feature.
#
# 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
# end
# end
class NullBatch < NullObject
attr_accessor :description
attr_reader :bid
Expand Down Expand Up @@ -49,7 +67,7 @@ def join
@callbacks.each do |event, callback, options|
if event != :success || failures == 0
case callback
when Class
when Class
callback.new.send("on_#{event}", self, options)
when String
klass, meth = callback.split('#')
Expand All @@ -71,7 +89,7 @@ def total
# :nocov:
RSpec.configure do |config|
config.before(:each) do |example|
next if example.metadata[:stub_batches] == false
next unless example.metadata[:stub_batches] == true

if mocked_with_mocha?
Sidekiq::Batch.stubs(:new) { RSpec::Sidekiq::NullBatch.new }
Expand Down
4 changes: 2 additions & 2 deletions spec/rspec/sidekiq/batch_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require 'spec_helper'

RSpec.describe 'Batch' do
RSpec.describe 'Batch', stub_batches: true do
module Sidekiq
module Batch
class Status
Expand Down Expand Up @@ -80,4 +80,4 @@ def foo(status, options); end
end
end
end
end
end

0 comments on commit 0863fb8

Please sign in to comment.