How to test a Sidekiq worker with RSpec?

9k views Asked by At

I'm doing a test using RSPEC, and used Sidekiq for background jobs.

Since, there's no generator for workers in rspec, not sure what to use.

https://relishapp.com/rspec/rspec-rails/docs/generators

require 'spec_helper'

RSpec.describe TestWorker, type: ? do # ex. :worker :sidekiq ...
  describe "TestWorker" do
    it "" do
     ....
    end
  end
end

bundle exec rspec spec/workers/test_worker_spec.rb

Doing like below, i'm getting: uninitialized constant TestWorker require 'spec_helper'

describe TestWorker do
  it "" do
   ....
  end
end

As i tried, gem rspec-sidekiq https://github.com/philostler/rspec-sidekiq

Can someone provide a sample template for testing app/workers/ in Rspec.

Thanks.

2

There are 2 answers

4
Kedarnag Mukanahallipatna On BEST ANSWER

I have not used the rspec-sidekiq gem, however, here is an example of how I am checking for Background jobs which uses sidekiq

# app/spec/workers/demo_worker_spec.rb

require 'rails_helper'
require 'sidekiq/testing'
Sidekiq::Testing.fake!

RSpec.describe DemoWorker, type: :worker do

  describe "Sidekiq Worker" do

    let (:demo) { FactoryGirl.create(:demo) }

    it "should respond to #perform" do
      expect(DemoWorker.new).to respond_to(:perform)
    end

    describe "Demo" do

      before do
        Sidekiq::Extensions.enable_delay!
        Sidekiq::Worker.clear_all
      end

      it "should enqueue a Email and SMS job" do
        assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
        Mailer.delay.demo_request(demo.id)
        assert_equal 1, Sidekiq::Extensions::DelayedMailer.jobs.size
      end

    end

  end

end
  1. As of I'm checking, if the instance responds to perform.
  2. Then, I'm asserting before and after the job is scheduled.
2
Ben On

You might sometimes want to test more than just the fact that the worker has been enqueud or not.

While it is better to decouple complex stuff that could happen in a worker's perform block, it can be tested as a standard class :

it { expect { MyWorker.new.perform }.to change { ...expectations... } }

or

it do
  MyWorker.new.perform
  ... expectations ..
end