2

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.

Sebastián Palma
  • 32,692
  • 6
  • 40
  • 59
aldrien.h
  • 3,437
  • 2
  • 30
  • 52

2 Answers2

6

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

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
Ben
  • 5,030
  • 6
  • 53
  • 94
  • 1
    Best to have at least some coverage around the queue. This doesn't test sidekiq can actually perform the job. I got caught out this way because my arguments were not proper JSON. – Rimian Mar 22 '22 at 03:13
  • Better sticking with the positional Arguments rather than using keyword arguments (json?), so then no need to think too much if sidekiq can perform depending on your input - it will just work. `MyWorker.new.perform` let you test as you would with standard classes. Testing if the job is enqued (the Have_enqueued_job matcher) is pointless if you actually want to test the job output – Ben Mar 22 '22 at 23:16