Git Product home page Git Product logo

rspec-sidekiq's Introduction

Welcome @wspurgin as new maintainer for rspec-sidekiq!

Gem Version Github Actions CI

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 a job array to enable testing (see the FAQ & Troubleshooting Wiki page). Thus, only include gem "rspec-sidekiq" in environments where this behaviour is required, such as the test group.

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_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.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)

# 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)

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

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

Describes when a job should be unique within its queue

sidekiq_options unique: true
# test with...
expect(AwesomeJob).to be_unique
it { is_expected.to be_unique }

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 that Sidekiq::Batch does. 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 spec

Maintainers

  • @wspurgin

Alumni

  • @packrat386
  • @philostler

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...

rspec-sidekiq's People

Contributors

3v0k4 avatar akihikodaki avatar aprescott avatar benmusch avatar bradhaydon avatar caalberts avatar chrismaximin avatar coding-bunny avatar dmasur avatar dsantosmerino avatar ericproulx avatar erikogan avatar fabiokr avatar futhr avatar geesu avatar graudeejs avatar mourad-ifeelgoods avatar nilsding avatar noreaster76 avatar packrat386 avatar petergoldstein avatar philostler avatar skunkworker avatar sosaucily avatar tarzan avatar trev avatar urkle avatar wpolicarpo avatar wspurgin avatar yelled3 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rspec-sidekiq's Issues

have_enqueued_job fails if args includes a Hash

In previous versions (2.0.0), if you had a worker that accepted a hash parameter, you could do the following test:

expect(Sidekiq::Worker).to have_enqueued_job 123, true, 'param1' => 'abc456'

After update to 2.1.0 it fails with: TypeError: no implicit conversion of String into Integer
at: lib/rspec/matchers/have_enqueued_job.rb:56

batch "stub" is not working

Once I upped to Sidekiq Pro, the rspec-sidekiq gem started borking all of my tests with the following error:

Failure/Error: Unable to find matching line from backtrace
NoMethodError:
undefined method `stub' for Sidekiq::Batch:Class

Not sure what the issue is, I will see if I can figure it out, but any help would def be appreciated.

#be_processed_in matcher using symbol vs string

A quick read of Sidekiq's code base appears to show that arguments of jobs are serialized to JSON for injection into Redis and are thus converted to strings automatically.

This means that the following statements are equal...

sidekiq_options queue: :download
sidekiq_options queue: "download"

...representing the same intent and the same end result.

However the the following written matchers are not equal...

it { should be_processed_in :download }
it { should be_processed_in "download" }

Should the matcher convert all expected values to strings by default so that an queue defined as :download passes when the matcher input is "download"?

testing the status on a Batch doesn't work

in the code below, I am trying to test for a potential race condition in sidekiqPro's Batch, and attempting to write a unit test for that condition. To do this, the Batch::Status for the batch needs to return something reasonable for the "total" attribute. right now, "total" just returns self(!). really threw me for a loop.

class SearchWorker < BaseWorker
def perform(search_id, user_id, channel_id)
# ...
sites = search.deserialize_courts

batch = Sidekiq::Batch.new
batch.jobs do
  sites.each do |site|
    SiteSearchWorker.perform_async(site.id, search_id, user_id, channel_id)
  end
end

status = Sidekiq::Batch::Status.new(batch.bid)

# status.join works
status.join

# status.total returns a NullStatus instead of an integer
if (status.total < sites.length)
  awesome_print status.total
  message = "Sidekiq Batch status total (#{status.total}) was less than sites searched (#{sites.length})!!!"
  raise message
end

...

end

I'll see if I can come up with a pull request, but any suggestions in the meantime?

Thanks!

NoMethodError: undefined method `configure' for RSpec:Module on CircleCI

I started getting this error after migration to rails 4.1.0

I use sidekiq-pro

bundle exec rake db:create db:schema:load --trace
rake aborted!
NoMethodError: undefined method `configure' for RSpec:Module
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/rspec-sidekiq-1.0.0/lib/rspec/sidekiq/batch.rb:31:in `<top (required)>'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/dependencies.rb:247:in `require'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/dependencies.rb:247:in `block in require'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/dependencies.rb:232:in `load_dependency'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/dependencies.rb:247:in `require'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/rspec-sidekiq-1.0.0/lib/rspec-sidekiq.rb:3:in `<top (required)>'
/home/ubuntu/.rvm/gems/ruby-2.0.0-p353@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:76:in `require'
/home/ubuntu/.rvm/gems/ruby-2.0.0-p353@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:76:in `block (2 levels) in require'
/home/ubuntu/.rvm/gems/ruby-2.0.0-p353@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:72:in `each'
/home/ubuntu/.rvm/gems/ruby-2.0.0-p353@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:72:in `block in require'
/home/ubuntu/.rvm/gems/ruby-2.0.0-p353@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:61:in `each'
/home/ubuntu/.rvm/gems/ruby-2.0.0-p353@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:61:in `require'
/home/ubuntu/.rvm/gems/ruby-2.0.0-p353@global/gems/bundler-1.6.2/lib/bundler.rb:132:in `require'
/home/ubuntu/seo_platform/config/application.rb:14:in `<top (required)>'
/home/ubuntu/seo_platform/Rakefile:4:in `require'
/home/ubuntu/seo_platform/Rakefile:4:in `<top (required)>'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/rake-10.2.2/lib/rake/rake_module.rb:28:in `load'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/rake-10.2.2/lib/rake/rake_module.rb:28:in `load_rakefile'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/rake-10.2.2/lib/rake/application.rb:677:in `raw_load_rakefile'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/rake-10.2.2/lib/rake/application.rb:94:in `block in load_rakefile'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/rake-10.2.2/lib/rake/application.rb:176:in `standard_exception_handling'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/rake-10.2.2/lib/rake/application.rb:93:in `load_rakefile'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/rake-10.2.2/lib/rake/application.rb:77:in `block in run'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/rake-10.2.2/lib/rake/application.rb:176:in `standard_exception_handling'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/rake-10.2.2/lib/rake/application.rb:75:in `run'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/gems/rake-10.2.2/bin/rake:33:in `<top (required)>'
/home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/bin/rake:23:in `load'
 /home/ubuntu/seo_platform/vendor/bundle/ruby/2.0.0/bin/rake:23:in `<main>'

Any thoughts?

undefined method 'jobs'

Hey!

Trying to get rspec-sidekiq to be working.

I was reading your initialization documents. I was under the impression that expect takes in a block instead of being called as a method.

expect { AwesomeJob } instead of expect( AwesomeJob )

Using expect as a method causes a ArgumentError (1 for 0).

If i make that assumption, when i call the expect job, i get the following error,
undefined method jobs' for #Proc:0x007fb7648e8578`.

Any ideas? Thanks!

How can I test using "within_sidekiq_retries_exhausted_block" with an outside method

I wanna test "sidekiq_retries_exhausted" in this class:

class PostListingsWorker
  include Sidekiq::Worker
  sidekiq_options :retry => 0

  sidekiq_retries_exhausted do |msg|
    NotifyMailer.warn_email(msg).deliver_now
  end

  def perform(params, fetch_time)
  ....
  end
end

Here is my test:

it 'should send email when retries exhausted' do
    msg = {error_message: 'Wrong', args: [{id: 1}]}.to_json
    PostListingsWorker.within_sidekiq_retries_exhausted_block(msg) {
      expect(PostListingsWorker).to receive(:"NotifyMailer.warn_email().deliver_now").with(msg)
    }
  end

But it doesn't work.Here is my log:

Failure/Error: expect(PostListingsWorker).to > >
receive(:"NotifyMailer.warn_email().deliver_now").with(:msg)
PostListingsWorker does not implement: NotifyMailer.warn_email().deliver_now

So,is there any way to test a method belong to another class during "sidekiq_retries_exhausted"?

New Matcher Idea: have_enqueued_jobs_in_bulk

While working on my gem: http://sidekiq-orm.github.io
I wanted to be able to test Sidekiq::ActiveRecord::ManagerWorker, which uses Sidekiq::Client.push_bulk, e.g

def batch_args(*ids)
  {class: custom_worker_class, args: ids.map{ |id| [id] }}
end

context 'as method arguments' do
  it 'pushes a bulk of all user ids for the specified worker_class' do
    expect(sidekiq_client).to receive(:push_bulk).with( batch_args(user_1.id, user_2.id, user_3.id) )
    run_worker({:worker_class => custom_worker_class})
  end
end

from: https://github.com/sidekiq-orm/sidekiq-activerecord/blob/master/spec/sidekiq/active_record/manager_worker_spec.rb#L77-L87

It would be great if I could do:

expect(custom_worker_class).to have_enqueued_jobs_in_bulk([ [id1], [id2] ])

for more info on Sidekiq::ActiveRecord::ManagerWorker :
https://github.com/sidekiq-orm/sidekiq-activerecord/wiki/Manager-Worker
https://github.com/sidekiq-orm/sidekiq-activerecord/blob/master/lib/sidekiq/active_record/manager_worker.rb

@philostler WDYT?

RSpec deprecation warnings

Using RSpec 3, I get the following message when using be_delayed:

Deprecation Warnings:
--------------------------------------------------------------------------------
RSpec::Sidekiq::Matchers::BeDelayed implements a legacy RSpec matcher
protocol. For the current protocol you should expose the failure messages
via the `failure_message` and `failure_message_when_negated` methods.

#be_delayed doesn't work

I can't figure out why #be_delayed matcher doesn't work for me :( Have the following code:

class SomeClass
  def call
    Object.delay.is_a?(Object)
  end
end

With spec:

require 'rails_helper'

describe SomeClass do
  subject { described_class.new }

  it 'does something' do
    subject.call
    expect(Object.method(:is_a?)).to be_delayed
  end
end

And running specs gives this:

10:58:11 - INFO - Running: spec/services/some_class_spec.rb
[rspec-sidekiq] WARNING! Sidekiq will *NOT* process jobs in this environment. See https://github.com/philostler/rspec-sidekiq/wiki/FAQ-&-Troubleshooting

SomeClass
  does something (FAILED - 1)

Failures:

  1) SomeClass does something
     Failure/Error: expect(Object.method(:is_a?)).to be_delayed
       expected Object.is_a? to be delayed
     # ./spec/services/some_class_spec.rb:8:in `block (2 levels) in <top (required)>'
     # ./spec/rails_helper.rb:61:in `block (3 levels) in <top (required)>'
     # ./spec/rails_helper.rb:60:in `block (2 levels) in <top (required)>'

Any suggestions?

Improve README

Generally improve quality of README and maybe move example up etc

Sidekiq::Batch::Status wrong number of arguments

I'm getting an ArgumentError exception when my specs try to instantiate an instance of Sidekiq::Batch::Status.

With one argument, I get ArgumentError Exception: wrong number of arguments (given 0, expected 2)
With 2+ arguments I get ArgumentError Exception: Wrong number of arguments. Expected 1, got n#

I placed a few break points in the file pertaining to batches and I see the call to the NullBatch initializer is called but not the call to NullStatus. Has anyone ever seen this type of behavior?

I also notice that the BatchStatus object only takes one argument, a bid, but the NullStatus takes both a bid and a callback. How does this work?

Print warning when used in development mode

I've had a number of issues where Sidekiq has stopped processing jobs in development mode. These all boiled down to people including rspec-sidekiq in the development group in their Gemfile. Could you please print a warning on bootup in the development environment since it is probably not what people want?

Bonus points: allow the user to disable the warning if they know they actually want to do this for some odd reason.

Remove have_enqueued_jobs matcher

Matcher is pointless given that you can do...

expect(AwesomeJob).to have(1).jobs
# or
expect(AwesomeJob).to have(1).enqueued.jobs

Remove, or ideally keep with a message telling people to use the other syntax

Warn: can't alias context from irb_context." error

When I use this gem in a Rails project by including rspec-sidekiq in my Gemfile:

group :test do
  gem 'fuubar'
end

I get a warning "irb: warn: can't alias context from irb_context." when I run bundle exec rails c

Bundler requiring Ruby v1.9.2

There's an old dependency somewhere that's causing bundler to require Ruby 1.9.2. I haven't spent too much time looking into why, but I wanted to get an issue logged before it slipped my mind.

[:~/Source/rspec-sidekiq] master ± bundle install
Fetching gem metadata from https://rubygems.org/.........
Fetching gem metadata from https://rubygems.org/..
Resolving dependencies...
Installing timers (1.1.0) 
Installing celluloid (0.14.0) 
Gem::InstallError: celluloid requires Ruby version >= 1.9.2.
An error occurred while installing celluloid (0.14.0), and Bundler cannot continue.
Make sure that `gem install celluloid -v '0.14.0'` succeeds before bundling.

New release? 2.1

Version 2.1 seems ready to roll, but it's not on rubygems yet. Perhaps time to make a release?

`have_enqueued_job` clashes with `rspec-rails` `3.4.0`

In rspec-rails we implemented support for asserting on wether or not an ActiveJob has been queued, unfortunately we used have_enqueued_job as the name for this matcher as we were unaware of this gem. This means that rspec-sidekiq will now clash with rspec-rails.

Given that our matcher is more generic I propose that the have_enqueued_job matcher in rspec-sidekiq be renamed to have_enqueued_sidekiq_job and then aliased back to have_enqueued_job when it's not otherwise defined. (We use the alias trick a fair bit in rspec-expectations to provide extra grammar for matchers so it's a pretty accepted technique).

I'd be happy to work on a PR for this if it's acceptable to you :)

require 'sidekiq/testing' problem

Hello~

after I installed this gem when executing guard it throws out an error as below:

undefined method `client_push' for module `Sidekiq::Worker::ClassMethods' (NameError)

I look it up on google and find this

sidekiq/sidekiq#615

so I think it is because there is a line of

require File.expand_path("../../config/environment", __FILE__)

in my code that cause this error, so is there a way I could put

require 'sidekiq/testing'

after this line while using this gem?

Thanks. :)

How can I test the scheduled time?

I have found this code on the Sidekiq page, but it has since been removed:

Collector.should have_queued_job_at(date_2,1)

Is this have_queued_job_at method part of the gem? it doesn't seem to be recognised. Is there any way to test the time that the job has been rescheduled to?

Just installing gem causes Sidekiq to stop enqueue jobs

Not sure if it's just latest release, but even just putting rspec-sidekiq in my gem file causes my 'perform_async' functions to stop enqueue Sidekiq jobs. When I monitor Redis, I can see that the entires aren't even being made in the Redis database. This while using my app in development, not while running specs.

If I remove the gem from Gemfile and re-bundle, everything works great.

[Patch] and [Q] how to use be_processed_in

Hello developer

Hello please review the following patch.
rspec-sidekiq version 0.3.0

Or could you tell me how to use be_processed_in?

Best regards.

Patch

diff --git a/lib/rspec/sidekiq/matchers/be_processed_in.rb b/lib/rspec/sidekiq/matchers/be_processed_in.rb
index ced8114..68a0095 100644
--- a/lib/rspec/sidekiq/matchers/be_processed_in.rb
+++ b/lib/rspec/sidekiq/matchers/be_processed_in.rb
@@ -19,7 +19,7 @@ module RSpec
         end

         def matches? job
-          @klass = job.class
+          @klass = job
           @actual = @klass.get_sidekiq_options["queue"]
           @actual == @expected
         end
@@ -30,4 +30,4 @@ module RSpec
       end
     end
   end
-end
\ No newline at end of file
+end

Error

I got the following error

1) MyWorker 
   Failure/Error: it { expect(MyWorker).to be_processed_in :test }
   NoMethodError:
     undefined method `get_sidekiq_options' for Class:Class

spec_file

describe MyWorker do 
  before { MyWorker.perform_async('foo', 'bar') }
  it { expect(MyWorker).to be_processed_in :test }
end

have_enqueued_job wrong number of arguments (3 for 0..1)

I get this error when I try to use this API. I'm afraid I'm using it incorrectly.

UnlockContentJob.perform_later(1, 2, 3)
expect(UnlockContentJob).to have_enqueued_job(1, 2, 3)
Failure/Error: expect(UnlockContentJob).to have_enqueued_job(1, 2, 3)

 ArgumentError:
   wrong number of arguments (3 for 0..1)

The docs show multiple args:

expect(AwesomeJob).to have_enqueued_job('Awesome', true)

UnlockContentJob is an ActiveJob subclass. Could that be why? Do I need to do something special to set up this gem for ActiveJob? It looked like the adapter was set by the gem.

Disable rspec-sidekiq

Hello,
first of all, thanks for this awesome gem :)

I'm currently using rspec-sidekiq, now I'd like to add a separate test with a real sidekiq connection so I'd like to disable this gem in an integration test (cucumber or rspec):

    describe MyWorker do

        before do
            # disable rspec-sidekiq here
        end

        it "really processes my worker" do
            10.times |i|
                MyWorker.perform_async i
            end
        end

    end

What is the right way to do achieve this?

Probably I should also put in a Procfile.test the following content and have it run before executing my integration test, what do you think?

    worker: bundle exec sidekiq -c 15

Regards,
Adit Saxena

Gem specs fail

Hey,

When I run the rspec-sidekiq specs locally using bundle exec rspec spec I get 4 failures:

rspec ./spec/rspec/sidekiq/matchers/have_enqueued_job_spec.rb:29 # RSpec::Sidekiq::Matchers::HaveEnqueuedJob expected usage matches on an enqueued ActiveJob
rspec ./spec/rspec/sidekiq/matchers/have_enqueued_job_spec.rb:33 # RSpec::Sidekiq::Matchers::HaveEnqueuedJob expected usage matches on an enqueued ActiveJob by global_id
rspec ./spec/rspec/sidekiq/matchers/have_enqueued_job_spec.rb:37 # RSpec::Sidekiq::Matchers::HaveEnqueuedJob expected usage matches on ActionMailer Job
rspec ./spec/rspec/sidekiq/matchers/have_enqueued_job_spec.rb:45 # RSpec::Sidekiq::Matchers::HaveEnqueuedJob expected usage matches on ActionMailer with a resource Job

All dependencies are installed. I tested this against both ruby 2.1.5 and the latest 2.2.4 and also both the develop branch and the master branch. Anything more than bundle exec rspec spec I need to run or be aware of?

does not work with rspec >= 3.0.0.beta

We have gem 'rspec-rails', '~> 3.0.0.beta' in the Gemfile.

On adding gem 'rspec-sidekiq', we get:

Bundler could not find compatible versions for gem "rspec-core":
  In Gemfile:
    rspec-sidekiq (>= 0) ruby depends on
      rspec-core (= 2.0.0) ruby

    rspec-rails (~> 3.0.0.beta) ruby depends on
      rspec-core (3.0.0.beta1)

Since rspec 3 is going to be in beta for sometime, it'd be good to fix it to work with pre released version(s).

have_enqueued_job and Sidekiq::Testing.disabled!

I'm running my specs with real Redis (via https://github.com/guilleiguaran/fakeredis), with Sidekiq::Testing.disable! and with this little hack to make thing working.

I think the problem is that have_enqueued_job doesn't look for jobs in Sidekiq::Queue object but rather Worker.jobs array. (it's my guess)

MyWorker.perform_async 'SuperAwesome'
=> "6983e6462239240363aa9280"

to ensure it's actually inside sidekiq queue I'll try:

Sidekiq::Queue.new('my que').to_a.first
=> #<Sidekiq::Job:0x007fb3ffdd4dd8
 @item=
  {"class"=>"MyWorker",
   "args"=>["SuperAwesome"],
   "queue"=>"my que",
   "jid"=>"6983e6462239240363aa9280",
   "created_at"=>1441896216.818053,
   "enqueued_at"=>1441896216.818154},
 @queue="leads",
 @value= ...

Now let's run matcher:

expect(MyWorker).to have_enqueued_job('SuperAwesome')
RSpec::Expectations::ExpectationNotMetError: expected to have an enqueued MyWorker job with arguments ["SuperAwesome"]

found: []

Dependency conflict with rspec 3.2

When I bump rspec-rails to ~>3.2.1 in my gemfile I get dependency conflicts:

Bundler could not find compatible versions for gem "rspec-mocks":
  In Gemfile:
    rspec-rails (~> 3.2.1) ruby depends on
      rspec-mocks (~> 3.2.0) ruby

    rspec-sidekiq (~> 2.0.0) ruby depends on
      rspec (>= 3.0.0, ~> 3.0) ruby depends on
        rspec-mocks (~> 3.1.0) ruby

NoMethodError: undefined method `jobs' for CustomJob:Class

I'm receiving an NoMethodError: undefined method jobs' for CustomJob:Class` error message when I run my specs, and I can't figure out why. I've checked #2 which seemed to be a similar issue, but I'm not making that mistake, and I'm using the latest versions of rspec-sidekiq (v2.1.0), Sidekiq (v3.4.2) and RSpec (v3.3.0).

My code is as follows:

it 'should have enqueued CustomJob' do
  x = 'something'
  y = 'something else'

  CustomJob.perform_later(x, y)
  expect(CustomJob).to have_enqueued_job(x, y)
end

After running this spec, I'm receiving:

Failures:
  1) CustomGateway should have enqueued CustomJob
     Failure/Error: expect(CustomJob).to have_enqueued_job(x, y)
     NoMethodError:
       undefined method `jobs' for CustomJob:Class

Any ideas about what I might be doing wrong? I'm not calling a "jobs" method anywhere in my code.
I've included the rspec-sidekiq gem in my Gemfile, which seems to be the only configuration required to get this up and running

Testing callbacks within batches?

In the Batches feature of Sidekiq Pro we can declare a callback to be called when the batch completes/succeeds.

rspec-sidekiq has made it much easier for us to test the batch functionality (which I appreciate!), but I don't see a way to test this callback functionality. I'm guessing it's because of the NullObject implementation of Batch, but I'm not sure.

Is there a way to test the callback functionality within rspec-sidekiq? Or, if not, any suggestions on how I might start tackling this PR?

be_processed_in always failing with new expect syntax

Given this worker:

class AwesomeJob
  include Sidekiq::Worker
  sidekiq_options :queue => :download

  def perform
  end
end

When I run the example listed in the README expect(AwesomeJob).to be_processed_in :download, I get the following error:

Failure/Error: expect(AwesomeJob).to be_processed_in :download
NoMethodError:
  undefined method `get_sidekiq_options' for Class:Class
# ./lib/rspec/sidekiq/matchers/be_processed_in.rb:23:in `matches?'

If I updated the test to say expect(AwesomeJob.new).to be_processed_in :download, though, then it passes. Am I doing something wrong, or is there a problem with the way that rspec-sidekiq handles the expect syntax?

If I use the older syntax it { should be_processed_in :download }, the test passes.

undefined method `raw_push'

I'm on Rails 4.0 RC1 with sidekiq 2.11.2 and rspec 2.13.1

When I include the gem:

group :test do
gem "rspec-sidekiq"
end

Rspec won't start and returns:
..../sidekiq-2.11.2/lib/sidekiq/testing.rb:5:in alias_method': undefined methodraw_push' for class `Class' (NameError)

I have not included rspec-sidekiq or sidekiq/testing in my spec_helper. Any Ideas?

Usage of :be_delayed with ActionMailer

Hi!

I can't seem to figure out how the be_delayed matcher from master is supposed to be used with ActionMailer classes. Since ActionMailer does some funky stuff with instance and class methods I can't use the matchers as documented.

expect(MyMailer.method :notification).to be_delayed('Hello')

fails with a NameError: undefined method.

I can work around that with a fake Method object like this:

expect(OpenStruct.new(receiver: MyMailer, name: :notification)).to be_delayed('Hello')

but that doesn't feel right at all.

Any hints on how the matcher is supposed to be used in this case are greatly appreciated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.