rspec-sidekiq 3.0.3 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGES.md +43 -0
- data/LICENSE +12 -0
- data/README.md +217 -84
- data/lib/rspec/sidekiq/batch.rb +30 -3
- data/lib/rspec/sidekiq/configuration.rb +13 -2
- data/lib/rspec/sidekiq/matchers/base.rb +262 -0
- data/lib/rspec/sidekiq/matchers/be_delayed.rb +17 -3
- data/lib/rspec/sidekiq/matchers/enqueue_sidekiq_job.rb +99 -0
- data/lib/rspec/sidekiq/matchers/have_enqueued_sidekiq_job.rb +25 -0
- data/lib/rspec/sidekiq/matchers.rb +13 -8
- data/lib/rspec/sidekiq/sidekiq.rb +1 -1
- data/lib/rspec/sidekiq/version.rb +1 -1
- data/lib/rspec-sidekiq.rb +2 -0
- metadata +130 -83
- data/.gitattributes +0 -22
- data/.gitignore +0 -2
- data/.rspec +0 -4
- data/.simplecov +0 -5
- data/Gemfile +0 -9
- data/lib/rspec/sidekiq/matchers/have_enqueued_job.rb +0 -183
- data/rspec-sidekiq.gemspec +0 -37
- data/spec/rspec/sidekiq/batch_spec.rb +0 -77
- data/spec/rspec/sidekiq/helpers/retries_exhausted_spec.rb +0 -40
- data/spec/rspec/sidekiq/matchers/be_delayed_spec.rb +0 -238
- data/spec/rspec/sidekiq/matchers/be_expired_in_spec.rb +0 -57
- data/spec/rspec/sidekiq/matchers/be_processed_in_spec.rb +0 -114
- data/spec/rspec/sidekiq/matchers/be_retryable_spec.rb +0 -129
- data/spec/rspec/sidekiq/matchers/be_unique_spec.rb +0 -115
- data/spec/rspec/sidekiq/matchers/have_enqueued_job_spec.rb +0 -228
- data/spec/rspec/sidekiq/matchers/save_backtrace_spec.rb +0 -136
- data/spec/rspec/sidekiq/sidekiq_spec.rb +0 -15
- data/spec/spec_helper.rb +0 -29
- data/spec/support/factories.rb +0 -33
- data/spec/support/init.rb +0 -6
- data/spec/support/test_action_mailer.rb +0 -6
- data/spec/support/test_job.rb +0 -6
- data/spec/support/test_resource.rb +0 -16
- data/spec/support/test_worker.rb +0 -8
- data/spec/support/test_worker_alternative.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a4f0ece401056914cf478dc4657d19aad569156ebf40ee29ee85c36fc430cfc3
|
4
|
+
data.tar.gz: 858c2c49ae54497a5201eab4cb3d9179fbe21a1684b11663719dfd17dd198cb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 831dfa10d07623e001f2253072b6d8e5311a0d887661421ba3eb914fce8f5020b73e5c7bda02264ebf4be6b6f23c2b02f8082a149d7ff5836895525ae61d697c
|
7
|
+
data.tar.gz: fda99d4e3bd9b43fb55ed60e96f77fd0ca54156bc6dcc42df3f1d2fb9323fff9fc63f5495a595766e937d0214fff10736ef18b9b468fccf4b97b91b2aae5e296
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,46 @@
|
|
1
|
+
4.1.0
|
2
|
+
---
|
3
|
+
* Add Composable support to `enqueue_sidekiq_job` and
|
4
|
+
`have_enqueued_sidekiq_job` (#211)
|
5
|
+
* Add `immediately` to specify that a job should be enqueued without any delay (#210)
|
6
|
+
|
7
|
+
4.0.2
|
8
|
+
---
|
9
|
+
* Explicitly require forwardable (#204)
|
10
|
+
|
11
|
+
4.0.1
|
12
|
+
---
|
13
|
+
* Restore the old normalizing expected args behavior with symbols (#205)
|
14
|
+
* fixes an unintentional breaking change in 4.0.0
|
15
|
+
|
16
|
+
4.0.0
|
17
|
+
---
|
18
|
+
* [BREAKING] Dropped support for matching jobs on ActiveJob's private API args, (e.g. `_aj_globalid` and `_aj_ruby2_keywords`). `_aj_globalid` can be replaced with the object itself, e.g. `have_enqueued_sidekiq_job(user)`.
|
19
|
+
* [BREAKING] Dropped support for Ruby 2.6
|
20
|
+
* [BREAKING] Mocking Sidekiq::Batch is now _opt in_ (was opt-out) by default
|
21
|
+
* [BREAKING] Dropped the `have_enqueued_job` matcher (deprecated since v3)
|
22
|
+
* [BREAKING] Dropped support for Sidekiq <5
|
23
|
+
* [BREAKING] Dropped support for Rails 5
|
24
|
+
* Add support for Sidekiq 7 (#192)
|
25
|
+
* Add support for builtin argument matchers from rspec mocks for
|
26
|
+
`have_enqueued_sidekiq_job` (#200)
|
27
|
+
* Add `#on` to `have_enqueued_sidekiq_job` to support testing queue at enqueue time (#197)
|
28
|
+
* Add `enqueue_sidekiq_job` for block-syntax style expectations
|
29
|
+
* Clarified `have_enqueued_sidekiq_job` error message to make it clear that the "actual arguments" list is an array of argument-lists across all enqueued jobs. (#195)
|
30
|
+
* Fix `in` and `at` evaluation to match Sidekiq (#194)
|
31
|
+
* Fix `be_delayed` argument matcher (#196)
|
32
|
+
* Fix argument matching ignoring order (#200)
|
33
|
+
* Fix `be_delayed` time math when using `delay_for` (#198)
|
34
|
+
|
35
|
+
3.1.0
|
36
|
+
---
|
37
|
+
* Add support for latest ruby and Rails 5 (coding-bunny #156)
|
38
|
+
* Support `Class#method` notation in batch callback (caalberts #155)
|
39
|
+
* Fix bug with time comparison in delayed jobs (geeosh #153 with help from col)
|
40
|
+
* remove usage of `Integer#blank?` (lanej #152)
|
41
|
+
* Add `NullBatch#description` (dsantosmerino #139)
|
42
|
+
* README updates (BenMusch #142, akihikodaki #141, wpolicarpo #160)
|
43
|
+
|
1
44
|
3.0.3
|
2
45
|
---
|
3
46
|
* Re-splat arguments for the have_enqueued_job alias (aprescott #136)
|
data/LICENSE
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
+
Copyright (c) 2023 Will Spurgin
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
+
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
10
|
+
|
11
|
+
Elements of this software and associated documentation files are covered by the following license:
|
12
|
+
|
13
|
+
The MIT License (MIT)
|
14
|
+
|
3
15
|
Copyright (c) 2014, 2015 Phil Ostler
|
4
16
|
|
5
17
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
data/README.md
CHANGED
@@ -1,23 +1,9 @@
|
|
1
|
-
**Welcome @
|
1
|
+
**Welcome @wspurgin as new maintainer for `rspec-sidekiq`!**
|
2
2
|
|
3
|
-
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/rspec-sidekiq.svg)](https://badge.fury.io/rb/rspec-sidekiq)
|
4
|
+
[![Github Actions CI][github_actions_badge]][github_actions]
|
4
5
|
|
5
|
-
|
6
|
-
[![Code Climate][code_climate_badge]][code_climate]
|
7
|
-
[![Travis CI][travis_ci_badge]][travis_ci]
|
8
|
-
[![Coveralls][coveralls_badge]][coveralls]
|
9
|
-
[![Gemnasium][gemnasium_badge]][gemnasium]
|
10
|
-
|
11
|
-
***Simple testing of Sidekiq jobs via a collection of matchers and helpers***
|
12
|
-
|
13
|
-
[RubyGems][ruby_gems] |
|
14
|
-
[Code Climate][code_climate] |
|
15
|
-
[GitHub][github] |
|
16
|
-
[Travis CI][travis_ci] |
|
17
|
-
[Coveralls][coveralls] |
|
18
|
-
[Gemnasium][gemnasium] |
|
19
|
-
[RubyDoc][ruby_doc] |
|
20
|
-
[Ruby Toolbox][ruby_toolbox]
|
6
|
+
Simple testing of Sidekiq jobs via a collection of matchers and helpers.
|
21
7
|
|
22
8
|
[Jump to Matchers »](#matchers) | [Jump to Helpers »](#helpers)
|
23
9
|
|
@@ -48,33 +34,159 @@ end
|
|
48
34
|
```
|
49
35
|
|
50
36
|
## Matchers
|
51
|
-
* [
|
37
|
+
* [enqueue_sidekiq_job](#enqueue_sidekiq_job)
|
38
|
+
* [have_enqueued_sidekiq_job](#have_enqueued_sidekiq_job)
|
52
39
|
* [be_processed_in](#be_processed_in)
|
53
40
|
* [be_retryable](#be_retryable)
|
54
41
|
* [be_unique](#be_unique)
|
55
|
-
* [
|
42
|
+
* [be_delayed (_deprecated_)](#be_delayed)
|
43
|
+
|
44
|
+
### enqueue_sidekiq_job
|
45
|
+
|
46
|
+
*Describes that the block should enqueue a job*. Optionally specify the
|
47
|
+
specific job class, arguments, timing, and other context
|
56
48
|
|
57
|
-
### be_delayed
|
58
|
-
*Describes a method that should be invoked asynchronously (See [Sidekiq Delayed Extensions][sidekiq_wiki_delayed_extensions])*
|
59
49
|
```ruby
|
60
|
-
|
61
|
-
expect
|
62
|
-
Object.delay.is_a? Object # delay with argument
|
63
|
-
expect(Object.method :is_a?).to be_delayed(Object)
|
50
|
+
# Basic
|
51
|
+
expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job
|
64
52
|
|
65
|
-
|
66
|
-
expect
|
67
|
-
Object.delay_for(1.hour).is_a? Object # delay for with argument
|
68
|
-
expect(Object.method :is_a?).to be_delayed(Object).for 1.hour
|
53
|
+
# A specific job class
|
54
|
+
expect { AwesomeJob.perform_async }.to enqueue_sidekiq_job(AwesomeJob)
|
69
55
|
|
70
|
-
|
71
|
-
expect
|
72
|
-
Object.delay_until(1.hour.from_now).is_a? Object # delay until with argument
|
73
|
-
expect(Object.method :is_a?).to be_delayed(Object).until 1.hour.from_now
|
56
|
+
# with specific arguments
|
57
|
+
expect { AwesomeJob.perform_async "Awesome!" }.to enqueue_sidekiq_job.with("Awesome!")
|
74
58
|
|
75
|
-
#
|
76
|
-
|
77
|
-
|
59
|
+
# On a specific queue
|
60
|
+
expect { AwesomeJob.set(queue: "high").perform_async }.to enqueue_sidekiq_job.on("high")
|
61
|
+
|
62
|
+
# At a specific datetime
|
63
|
+
specific_time = 1.hour.from_now
|
64
|
+
expect { AwesomeJob.perform_at(specific_time) }.to enqueue_sidekiq_job.at(specific_time)
|
65
|
+
|
66
|
+
# In a specific interval (be mindful of freezing or managing time here)
|
67
|
+
freeze_time do
|
68
|
+
expect { AwesomeJob.perform_in(1.hour) }.to enqueue_sidekiq_job.in(1.hour)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Combine and chain them as desired
|
72
|
+
expect { AwesomeJob.perform_at(specific_time, "Awesome!") }.to(
|
73
|
+
enqueue_sidekiq_job(AwesomeJob)
|
74
|
+
.with("Awesome!")
|
75
|
+
.on("default")
|
76
|
+
.at(specific_time)
|
77
|
+
)
|
78
|
+
|
79
|
+
# Also composable
|
80
|
+
expect do
|
81
|
+
AwesomeJob.perform_async
|
82
|
+
OtherJob.perform_async
|
83
|
+
end.to enqueue_sidekiq_job(AwesomeJob).and enqueue_sidekiq_job(OtherJob)
|
84
|
+
```
|
85
|
+
|
86
|
+
### have_enqueued_sidekiq_job
|
87
|
+
|
88
|
+
Describes that there should be an enqueued job with the **specified arguments**
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
AwesomeJob.perform_async 'Awesome', true
|
92
|
+
# test with...
|
93
|
+
expect(AwesomeJob).to have_enqueued_sidekiq_job('Awesome', true)
|
94
|
+
```
|
95
|
+
|
96
|
+
You can use the built-in RSpec args matchers too:
|
97
|
+
```ruby
|
98
|
+
AwesomeJob.perform_async({"something" => "Awesome", "extra" => "stuff"})
|
99
|
+
|
100
|
+
# using built-in matchers from rspec-mocks:
|
101
|
+
expect(AwesomeJob).to have_enqueued_sidekiq_job(hash_including("something" => "Awesome"))
|
102
|
+
expect(AwesomeJob).to have_enqueued_sidekiq_job(any_args)
|
103
|
+
expect(AwesomeJob).to have_enqueued_sidekiq_job(hash_excluding("bad_stuff" => anything))
|
104
|
+
|
105
|
+
# composable as well
|
106
|
+
expect(AwesomeJob).to have_enqueued_sidekiq_job(any_args).and have_enqueued_sidekiq_job(hash_including("something" => "Awesome"))
|
107
|
+
```
|
108
|
+
|
109
|
+
#### Testing scheduled jobs
|
110
|
+
|
111
|
+
*Use chainable matchers `#at`, `#in` and `#immediately`*
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
time = 5.minutes.from_now
|
115
|
+
AwesomeJob.perform_at time, 'Awesome', true
|
116
|
+
# test with...
|
117
|
+
expect(AwesomeJob).to have_enqueued_sidekiq_job('Awesome', true).at(time)
|
118
|
+
```
|
119
|
+
```ruby
|
120
|
+
AwesomeJob.perform_in 5.minutes, 'Awesome', true
|
121
|
+
# test with...
|
122
|
+
expect(AwesomeJob).to have_enqueued_sidekiq_job('Awesome', true).in(5.minutes)
|
123
|
+
```
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
# Job scheduled for a date in the past are enqueued immediately.
|
127
|
+
AwesomeJob.perform_later 5.minutes.ago, 'Awesome', true # equivalent to: AwesomeJob.perform_async 'Awesome', true
|
128
|
+
# test with...
|
129
|
+
expect(AwesomeJob).to have_enqueued_sidekiq_job('Awesome', true).immediately
|
130
|
+
```
|
131
|
+
|
132
|
+
#### Testing queue set for job
|
133
|
+
|
134
|
+
Use the chainable `#on` matcher
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
class AwesomeJob
|
138
|
+
include Sidekiq::Job
|
139
|
+
|
140
|
+
sidekiq_options queue: :low
|
141
|
+
end
|
142
|
+
|
143
|
+
AwesomeJob.perform_async("a little awesome")
|
144
|
+
|
145
|
+
# test with..
|
146
|
+
expect(AwesomeJob).to have_enqueued_sidekiq_job("a little awesome").on("low")
|
147
|
+
|
148
|
+
# Setting the queue when enqueuing
|
149
|
+
AwesomeJob.set(queue: "high").perform_async("Very Awesome!")
|
150
|
+
|
151
|
+
expect(AwesomeJob).to have_enqueued_sidekiq_job("Very Awesome!").on("high")
|
152
|
+
```
|
153
|
+
|
154
|
+
#### Testing ActiveMailer jobs
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
user = User.first
|
158
|
+
AwesomeActionMailer.invite(user, true).deliver_later
|
159
|
+
|
160
|
+
expect(Sidekiq::Worker).to have_enqueued_sidekiq_job(
|
161
|
+
"AwesomeActionMailer",
|
162
|
+
"invite",
|
163
|
+
"deliver_now",
|
164
|
+
user,
|
165
|
+
true
|
166
|
+
)
|
167
|
+
```
|
168
|
+
|
169
|
+
#### Testing a job is _not_ enqueued
|
170
|
+
|
171
|
+
The negative case for `have_enqueued_sidekiq_job` is provided, but it's
|
172
|
+
important to remember that `have_enqueued_sidekiq_job` is an expectation that a
|
173
|
+
job is enqueued _with specific arguments_. In other words, passing no arguments
|
174
|
+
to `have_enqueued_sidekiq_job` is implicitly telling the matcher to look for
|
175
|
+
jobs _without_ arguments.
|
176
|
+
|
177
|
+
In short, unless you tell the matcher that _no_ jobs with _any_ arguments should be enqueued, you'll get the wrong result:
|
178
|
+
|
179
|
+
```ruby
|
180
|
+
# example this is a test that we'd expect to fail
|
181
|
+
AwesomeJob.perform_async "Actually not awesome"
|
182
|
+
|
183
|
+
### BAD - saying there shouldn't be a job enqueued _without_ args
|
184
|
+
expect(AwesomeJob).not_to have_enqueued_sidekiq_job
|
185
|
+
# => passes! 😱 Our job was enqueued _with_ args so no job exists without args.
|
186
|
+
|
187
|
+
### Good
|
188
|
+
expect(AwesomeJob).not_to have_enqueued_sidekiq_job(any_args)
|
189
|
+
# => fails
|
78
190
|
```
|
79
191
|
|
80
192
|
### be_processed_in
|
@@ -87,7 +199,7 @@ it { is_expected.to be_processed_in :download }
|
|
87
199
|
```
|
88
200
|
|
89
201
|
### be_retryable
|
90
|
-
*Describes if a job should retry when there is a failure in
|
202
|
+
*Describes if a job should retry when there is a failure in its execution*
|
91
203
|
```ruby
|
92
204
|
sidekiq_options retry: 5
|
93
205
|
# test with...
|
@@ -102,13 +214,13 @@ it { is_expected.to be_retryable false }
|
|
102
214
|
```
|
103
215
|
|
104
216
|
### save_backtrace
|
105
|
-
*Describes if a job should save the error backtrace when there is a failure in
|
217
|
+
*Describes if a job should save the error backtrace when there is a failure in its execution*
|
106
218
|
```ruby
|
107
219
|
sidekiq_options backtrace: 5
|
108
220
|
# test with...
|
109
221
|
expect(AwesomeJob).to save_backtrace # or
|
110
222
|
it { is_expected.to save_backtrace }
|
111
|
-
# ...or alternatively
|
223
|
+
# ...or alternatively specify the number of lines that should be saved
|
112
224
|
expect(AwesomeJob).to save_backtrace 5 # or
|
113
225
|
it { is_expected.to save_backtrace 5 }
|
114
226
|
# ...or when it should not save the backtrace
|
@@ -119,7 +231,7 @@ it { is_expected.to save_backtrace false }
|
|
119
231
|
```
|
120
232
|
|
121
233
|
### be_unique
|
122
|
-
*Describes when a job should be unique within
|
234
|
+
*Describes when a job should be unique within its queue*
|
123
235
|
```ruby
|
124
236
|
sidekiq_options unique: true
|
125
237
|
# test with...
|
@@ -136,33 +248,32 @@ it { is_expected.to be_expired_in 1.hour }
|
|
136
248
|
it { is_expected.to_not be_expired_in 2.hours }
|
137
249
|
```
|
138
250
|
|
139
|
-
###
|
140
|
-
*Describes that there should be an enqueued job with the specified arguments*
|
251
|
+
### be_delayed
|
141
252
|
|
142
|
-
**
|
143
|
-
|
253
|
+
**This matcher is deprecated**. Use of it with Sidekiq 7+ will raise an error.
|
254
|
+
Sidekiq 7 [dropped Delayed
|
255
|
+
Extensions](https://github.com/sidekiq/sidekiq/issues/5076).
|
144
256
|
|
257
|
+
*Describes a method that should be invoked asynchronously (See [Sidekiq Delayed Extensions][sidekiq_wiki_delayed_extensions])*
|
145
258
|
```ruby
|
146
|
-
|
147
|
-
|
148
|
-
|
259
|
+
Object.delay.is_nil? # delay
|
260
|
+
expect(Object.method :is_nil?).to be_delayed
|
261
|
+
Object.delay.is_a? Object # delay with argument
|
262
|
+
expect(Object.method :is_a?).to be_delayed(Object)
|
149
263
|
|
150
|
-
#
|
151
|
-
|
152
|
-
|
153
|
-
|
264
|
+
Object.delay_for(1.hour).is_nil? # delay for
|
265
|
+
expect(Object.method :is_nil?).to be_delayed.for 1.hour
|
266
|
+
Object.delay_for(1.hour).is_a? Object # delay for with argument
|
267
|
+
expect(Object.method :is_a?).to be_delayed(Object).for 1.hour
|
154
268
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
Awesomejob.perform_in 5.minutes, 'Awesome', true
|
164
|
-
# test with...
|
165
|
-
expect(AwesomeJob).to have_enqueued_sidekiq_job('Awesome', true).in(5.minutes)
|
269
|
+
Object.delay_until(1.hour.from_now).is_nil? # delay until
|
270
|
+
expect(Object.method :is_nil?).to be_delayed.until 1.hour.from_now
|
271
|
+
Object.delay_until(1.hour.from_now).is_a? Object # delay until with argument
|
272
|
+
expect(Object.method :is_a?).to be_delayed(Object).until 1.hour.from_now
|
273
|
+
|
274
|
+
#Rails Mailer
|
275
|
+
MyMailer.delay.some_mail
|
276
|
+
expect(MyMailer.instance_method :some_mail).to be_delayed
|
166
277
|
```
|
167
278
|
|
168
279
|
## Example matcher usage
|
@@ -184,11 +295,38 @@ end
|
|
184
295
|
```
|
185
296
|
|
186
297
|
## Helpers
|
187
|
-
* [Batches (Sidekiq Pro)](#batches)
|
298
|
+
* [Batches (Sidekiq Pro) _experimental_](#batches)
|
188
299
|
* [`within_sidekiq_retries_exhausted_block`](#within_sidekiq_retries_exhausted_block)
|
189
300
|
|
190
301
|
### Batches
|
191
|
-
|
302
|
+
|
303
|
+
If you are using Sidekiq Batches ([Sidekiq Pro feature][sidekiq_wiki_batches]),
|
304
|
+
You can *opt-in* with `stub_batches` to make `rspec-sidekiq` mock the
|
305
|
+
implementation (using a NullObject pattern). This enables testing without a
|
306
|
+
Redis instance. Mocha and RSpec stubbing is supported here.
|
307
|
+
|
308
|
+
:warning: **Caution**: Opting-in to this feature, while allowing you to test without
|
309
|
+
having Redis, _does not_ provide the exact API that `Sidekiq::Batch` does. As
|
310
|
+
such it can cause surprises.
|
311
|
+
|
312
|
+
|
313
|
+
```ruby
|
314
|
+
RSpec.describe "Using mocked batches", stub_batches: true do
|
315
|
+
it "uses mocked batches" do
|
316
|
+
batch = Sidekiq::Batch.new
|
317
|
+
batch.jobs do
|
318
|
+
SomeJob.perform_async 123
|
319
|
+
end
|
320
|
+
|
321
|
+
expect(SomeJob).to have_enqueued_sidekiq_job
|
322
|
+
|
323
|
+
# Caution, the NullObject pattern means that the mocked Batch implementation
|
324
|
+
# responds to anything... even if it's not on the true `Sidekiq::Batch` API
|
325
|
+
# For example, the following fails
|
326
|
+
expect { batch.foobar! }.to raise_error(NoMethodError)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
```
|
192
330
|
|
193
331
|
### within_sidekiq_retries_exhausted_block
|
194
332
|
```ruby
|
@@ -202,10 +340,15 @@ FooClass.within_sidekiq_retries_exhausted_block {
|
|
202
340
|
```
|
203
341
|
|
204
342
|
## Testing
|
205
|
-
```
|
343
|
+
```
|
344
|
+
bundle exec rspec spec
|
345
|
+
```
|
206
346
|
|
207
347
|
## Maintainers
|
208
|
-
* @
|
348
|
+
* @wspurgin
|
349
|
+
|
350
|
+
### Alumni
|
351
|
+
|
209
352
|
* @packrat386
|
210
353
|
* @philostler
|
211
354
|
|
@@ -214,20 +357,10 @@ Please do! If there's a feature missing that you'd love to see then get in on th
|
|
214
357
|
|
215
358
|
Issues/Pull Requests/Comments all welcome...
|
216
359
|
|
217
|
-
[
|
218
|
-
[
|
219
|
-
[
|
220
|
-
|
221
|
-
[
|
222
|
-
[
|
223
|
-
[
|
224
|
-
[github]: http://github.com/philostler/rspec-sidekiq
|
225
|
-
[ruby_doc]: http://rubydoc.info/gems/rspec-sidekiq/frames
|
226
|
-
[ruby_gems]: http://rubygems.org/gems/rspec-sidekiq
|
227
|
-
[ruby_toolbox]: http://www.ruby-toolbox.com/projects/rspec-sidekiq
|
228
|
-
[travis_ci]: http://travis-ci.org/philostler/rspec-sidekiq
|
229
|
-
[travis_ci_badge]: https://travis-ci.org/philostler/rspec-sidekiq.svg?branch=develop
|
230
|
-
|
231
|
-
[rspec_sidekiq_wiki_faq_&_troubleshooting]: https://github.com/philostler/rspec-sidekiq/wiki/FAQ-&-Troubleshooting
|
232
|
-
[sidekiq_wiki_batches]: https://github.com/mperham/sidekiq/wiki/Batches
|
233
|
-
[sidekiq_wiki_delayed_extensions]: https://github.com/mperham/sidekiq/wiki/Delayed-Extensions
|
360
|
+
[github]: http://github.com/wspurgin/rspec-sidekiq
|
361
|
+
[github_actions]: https://github.com/wspurgin/rspec-sidekiq/actions
|
362
|
+
[github_actions_badge]: https://github.com/wspurgin/rspec-sidekiq/actions/workflows/main.yml/badge.svg
|
363
|
+
|
364
|
+
[rspec_sidekiq_wiki_faq_&_troubleshooting]: https://github.com/wspurgin/rspec-sidekiq/wiki/FAQ-&-Troubleshooting
|
365
|
+
[sidekiq_wiki_batches]: https://github.com/sidekiq/sidekiq/wiki/Batches
|
366
|
+
[sidekiq_wiki_delayed_extensions]: https://github.com/sidekiq/sidekiq/wiki/Delayed-Extensions
|
data/lib/rspec/sidekiq/batch.rb
CHANGED
@@ -9,7 +9,26 @@ if defined? Sidekiq::Batch
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
##
|
13
|
+
# Sidekiq::Batch is a Sidekiq::Pro feature. However the general consensus is
|
14
|
+
# that, by defeault, you can't test without redis. RSpec::Sidekiq includes
|
15
|
+
# a "null object" pattern implementation to mock Batches. This will mock
|
16
|
+
# Sidekiq::Batch and prevent it from using Redis.
|
17
|
+
#
|
18
|
+
# This is _opt-in_ only feature.
|
19
|
+
#
|
20
|
+
# RSpec.describe "Using mocked batches", stub_batches: true do
|
21
|
+
# it "uses mocked batches" do
|
22
|
+
# batch = Sidekiq::Batch.new
|
23
|
+
# batch.jobs do
|
24
|
+
# SomeJob.perform_async 123
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# expect(SomeJob).to have_enqueued_sidekiq_job
|
28
|
+
# end
|
29
|
+
# end
|
12
30
|
class NullBatch < NullObject
|
31
|
+
attr_accessor :description
|
13
32
|
attr_reader :bid
|
14
33
|
|
15
34
|
def initialize(bid = nil)
|
@@ -45,9 +64,17 @@ if defined? Sidekiq::Batch
|
|
45
64
|
def join
|
46
65
|
::Sidekiq::Worker.drain_all
|
47
66
|
|
48
|
-
@callbacks.each do |event,
|
67
|
+
@callbacks.each do |event, callback, options|
|
49
68
|
if event != :success || failures == 0
|
50
|
-
|
69
|
+
case callback
|
70
|
+
when Class
|
71
|
+
callback.new.send("on_#{event}", self, options)
|
72
|
+
when String
|
73
|
+
klass, meth = callback.split('#')
|
74
|
+
klass.constantize.new.send(meth, self, options)
|
75
|
+
else
|
76
|
+
raise ArgumentError, 'Unsupported callback notation'
|
77
|
+
end
|
51
78
|
end
|
52
79
|
end
|
53
80
|
end
|
@@ -62,7 +89,7 @@ if defined? Sidekiq::Batch
|
|
62
89
|
# :nocov:
|
63
90
|
RSpec.configure do |config|
|
64
91
|
config.before(:each) do |example|
|
65
|
-
next
|
92
|
+
next unless example.metadata[:stub_batches] == true
|
66
93
|
|
67
94
|
if mocked_with_mocha?
|
68
95
|
Sidekiq::Batch.stubs(:new) { RSpec::Sidekiq::NullBatch.new }
|
@@ -1,13 +1,24 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
|
1
3
|
module RSpec
|
2
4
|
module Sidekiq
|
3
5
|
class Configuration
|
4
|
-
attr_accessor :clear_all_enqueued_jobs,
|
6
|
+
attr_accessor :clear_all_enqueued_jobs,
|
7
|
+
:enable_terminal_colours,
|
8
|
+
:warn_when_jobs_not_processed_by_sidekiq
|
5
9
|
|
6
10
|
def initialize
|
7
|
-
|
11
|
+
# Display settings defaults
|
8
12
|
@enable_terminal_colours = true
|
13
|
+
|
14
|
+
# Functional settings defaults
|
15
|
+
@clear_all_enqueued_jobs = true
|
9
16
|
@warn_when_jobs_not_processed_by_sidekiq = true
|
10
17
|
end
|
18
|
+
|
19
|
+
def sidekiq_gte_7?
|
20
|
+
Gem::Version.new(::Sidekiq::VERSION) >= Gem::Version.new("7.0.0")
|
21
|
+
end
|
11
22
|
end
|
12
23
|
end
|
13
24
|
end
|