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.
Files changed (40) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES.md +43 -0
  3. data/LICENSE +12 -0
  4. data/README.md +217 -84
  5. data/lib/rspec/sidekiq/batch.rb +30 -3
  6. data/lib/rspec/sidekiq/configuration.rb +13 -2
  7. data/lib/rspec/sidekiq/matchers/base.rb +262 -0
  8. data/lib/rspec/sidekiq/matchers/be_delayed.rb +17 -3
  9. data/lib/rspec/sidekiq/matchers/enqueue_sidekiq_job.rb +99 -0
  10. data/lib/rspec/sidekiq/matchers/have_enqueued_sidekiq_job.rb +25 -0
  11. data/lib/rspec/sidekiq/matchers.rb +13 -8
  12. data/lib/rspec/sidekiq/sidekiq.rb +1 -1
  13. data/lib/rspec/sidekiq/version.rb +1 -1
  14. data/lib/rspec-sidekiq.rb +2 -0
  15. metadata +130 -83
  16. data/.gitattributes +0 -22
  17. data/.gitignore +0 -2
  18. data/.rspec +0 -4
  19. data/.simplecov +0 -5
  20. data/Gemfile +0 -9
  21. data/lib/rspec/sidekiq/matchers/have_enqueued_job.rb +0 -183
  22. data/rspec-sidekiq.gemspec +0 -37
  23. data/spec/rspec/sidekiq/batch_spec.rb +0 -77
  24. data/spec/rspec/sidekiq/helpers/retries_exhausted_spec.rb +0 -40
  25. data/spec/rspec/sidekiq/matchers/be_delayed_spec.rb +0 -238
  26. data/spec/rspec/sidekiq/matchers/be_expired_in_spec.rb +0 -57
  27. data/spec/rspec/sidekiq/matchers/be_processed_in_spec.rb +0 -114
  28. data/spec/rspec/sidekiq/matchers/be_retryable_spec.rb +0 -129
  29. data/spec/rspec/sidekiq/matchers/be_unique_spec.rb +0 -115
  30. data/spec/rspec/sidekiq/matchers/have_enqueued_job_spec.rb +0 -228
  31. data/spec/rspec/sidekiq/matchers/save_backtrace_spec.rb +0 -136
  32. data/spec/rspec/sidekiq/sidekiq_spec.rb +0 -15
  33. data/spec/spec_helper.rb +0 -29
  34. data/spec/support/factories.rb +0 -33
  35. data/spec/support/init.rb +0 -6
  36. data/spec/support/test_action_mailer.rb +0 -6
  37. data/spec/support/test_job.rb +0 -6
  38. data/spec/support/test_resource.rb +0 -16
  39. data/spec/support/test_worker.rb +0 -8
  40. data/spec/support/test_worker_alternative.rb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: dd244416f99c35639675efb4b3473dd9741d512c
4
- data.tar.gz: 6fa5eb3e029086fe4d316a6a9896b7acddb834de
2
+ SHA256:
3
+ metadata.gz: a4f0ece401056914cf478dc4657d19aad569156ebf40ee29ee85c36fc430cfc3
4
+ data.tar.gz: 858c2c49ae54497a5201eab4cb3d9179fbe21a1684b11663719dfd17dd198cb2
5
5
  SHA512:
6
- metadata.gz: fe360471b5c79f74e4af320881d97d0d26ec0cf837a8309e8b898221d71c63bce2d2a750d32b9427dfb931dc4a83837e4c2e3e6b1ddd6a5ed17050205f7e4aa3
7
- data.tar.gz: 1d0913303fbdd4c72aea0248e815d4842a5c8fe9d0a338c6cad7cf0dbd59fc7145899718d51185444c72023772605e30099326c8481345927f083c9db91df7e6
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 @wpolicarpo and @packrat386 as new maintainers for `rspec-sidekiq`!**
1
+ **Welcome @wspurgin as new maintainer for `rspec-sidekiq`!**
2
2
 
3
- # RSpec for Sidekiq
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
- [![RubyGems][gem_version_badge]][ruby_gems]
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 &raquo;](#matchers) | [Jump to Helpers &raquo;](#helpers)
23
9
 
@@ -48,33 +34,159 @@ end
48
34
  ```
49
35
 
50
36
  ## Matchers
51
- * [be_delayed](#be_delayed)
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
- * [have_enqueued_sidekiq_job](#have_enqueued_sidekiq_job)
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
- Object.delay.is_nil? # delay
61
- expect(Object.method :is_nil?).to be_delayed
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
- Object.delay_for(1.hour).is_nil? # delay for
66
- expect(Object.method :is_nil?).to be_delayed.for 1.hour
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
- Object.delay_until(1.hour.from_now).is_nil? # delay until
71
- expect(Object.method :is_nil?).to be_delayed.until 1.hour.from_now
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
- #Rails Mailer
76
- MyMailer.delay.some_mail
77
- expect(MyMailer.instance_method :some_mail).to be_delayed
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 it's execution*
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 it's execution*
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 specifiy the number of lines that should be saved
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 it's queue*
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
- ### have_enqueued__sidekiq_job
140
- *Describes that there should be an enqueued job with the specified arguments*
251
+ ### be_delayed
141
252
 
142
- **Note:** When using rspec-rails >= 3.4, use `have_enqueued_sidekiq_job` instead to
143
- prevent a name clash with rspec-rails' ActiveJob matcher.
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
- AwesomeJob.perform_async 'Awesome', true
147
- # test with...
148
- expect(AwesomeJob).to have_enqueued_sidekiq_job('Awesome', true)
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
- # Code written with older versions of the gem may use the deprecated
151
- # have_enqueued_job matcher.
152
- expect(AwesomeJob).to have_enqueued_job('Awesome', true)
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
- #### Testing scheduled jobs
156
- *Use chainable matchers `#at` and `#in`*
157
- ```ruby
158
- Awesomejob.perform_at 5.minutes.from_now, 'Awesome', true
159
- # test with...
160
- expect(AwesomeJob).to have_enqueued_sidekiq_job('Awesome', true).at(5.minutes.from_now)
161
- ```
162
- ```ruby
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
- 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.
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
- ```bundle exec rspec spec```
343
+ ```
344
+ bundle exec rspec spec
345
+ ```
206
346
 
207
347
  ## Maintainers
208
- * @wpolicarpo
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
- [code_climate]: https://codeclimate.com/github/philostler/rspec-sidekiq
218
- [code_climate_badge]: https://codeclimate.com/github/philostler/rspec-sidekiq.svg
219
- [coveralls]: https://coveralls.io/r/philostler/rspec-sidekiq
220
- [coveralls_badge]: https://img.shields.io/coveralls/philostler/rspec-sidekiq.svg?branch=develop
221
- [gem_version_badge]: https://badge.fury.io/rb/rspec-sidekiq.svg
222
- [gemnasium]: https://gemnasium.com/philostler/rspec-sidekiq
223
- [gemnasium_badge]: https://gemnasium.com/philostler/rspec-sidekiq.svg
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
@@ -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, callback_class, options|
67
+ @callbacks.each do |event, callback, options|
49
68
  if event != :success || failures == 0
50
- callback_class.new.send("on_#{event}", self, options)
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 if example.metadata[:stub_batches] == false
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, :enable_terminal_colours, :warn_when_jobs_not_processed_by_sidekiq
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
- @clear_all_enqueued_jobs = true
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