Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing sidekiq perform_in with RSpec 3

RSpec 3 and sidekiq 3.2.1. And I have setup sidekiq and rspec-sidekiq properly.

Suppose I have a worker called WeatherJob, which will change the weather status from sunny to rainy:

class WeatherJob
  include Sidekiq::Worker

  def perform record_id
    weather = Weather.find record_id

    weather.update status: 'rainy'
  end
end

I use this worker like this:

WeatherJob.perform_in 15.minutes, weather.id.

In the spec, I use Timecop to mock time:

require 'rails_helper'

describe WeatherJob do
  let(:weather) { create :weather, status: 'sunny' }
  let(:now)     { Time.current }

  it 'enqueue a job' do
    expect {
      WeatherJob.perform_async weather.id
    }.to change(WeatherJob.jobs, :size).by 1
  end

  context '15 mins later' do
    before do
      Timecop.freeze(now) do
        Weather.perform_in 15.minutes, weather.id
      end
    end

    it 'update to rainy' do
      Timecop.freeze(now + 16.minutes) do
        expect(weather.status).to eq 'rainy'
      end
    end
  end
end

I could see there is job in Weather.jobs array. And time is correctly 16 mins after. But it did not execute the job? Any advices? Thanks!

like image 870
Juanito Fatas Avatar asked Aug 11 '14 14:08

Juanito Fatas


People also ask

How do I test my Sidekiq scheduler?

On the browser, goto ==> http://localhost:{port}/sidekiq/recurring-jobs . where {port} is the port your application is running in. You will see the list of scheduled jobs for your application and some other details about it. Save this answer.

How do I test my Sidekiq worker?

To test your Sidekiq Worker jobs array, run WorkerNameHere.jobs in terminal and see if it contains your job with your jid. If it does, then it was enqueued in Sidekiq to be run as a job.

What is Sidekiq testing inline?

The Sidekiq::Testing.inline! testing mode executes the jobs immediately when they are placed in the queue. In my opinion, this should be the default testing mode for Sidekiq.


1 Answers

Sidekiq has three testing modes: disabled, fake, and inline. The default is fake, which just pushes all jobs into a jobs array and is the behavior you are seeing. The inline mode runs the job immediately instead of enqueuing it.

To force Sidekiq to run the job inline during the test, wrap your test code in a Sidekiq::Testing.inline! block:

before do
  Sidekiq::Testing.inline! do
    Timecop.freeze(now) do
      Weather.perform_in 15.minutes, weather.id
    end
  end
end

For more info on testing Sidekiq, refer to the official Testing wiki page.

like image 134
infused Avatar answered Oct 04 '22 23:10

infused