Dedy Puji
Dedy Puji

Reputation: 625

Rspec test retry_on

i have a job like this

class CrawlSsbHistory < BaseJob
    retry_on(Ssb::SessionExpired) do
      Ssb::Login.call
    end

    def perform
      response = Ssb::Client.get_data
      SsbHistory.last.destroy
    end
  end

and i have test like this

it "retries the job if session error" do
      allow(Ssb::Client).to receive(:get_data).and_raise(Ssb::SessionExpired)
      allow(Ssb::Login).to receive(:call)
      described_class.perform_now # it is CrawlSsbHistory
      expect(Ssb::Login).to have_received(:call)
    end

CrawlSsbHistory is a job to crawl some data. it call Ssb::Client.get_data to get the data.

Inside Ssb::Client.get_data i raise Ssb::SessionExpired if the session expired. so then i can capture the raised error on the job using retry_on. Then if it is happened i want to try the job.

but i got error like this

(Ssb::Login (class)).call(*(any args))
           expected: 1 time with any arguments
           received: 0 times with any arguments

Does the job no call retry_on? or do i test it wrong? how to make a rspec to test that retry_on is working and the Ssb::Login.call is called?

Upvotes: 1

Views: 1171

Answers (2)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230346

retry_on does not call the block immediately, on each retry. Only when attempts are exhausted. Otherwise, it just reschedules the job.

From the documentation:

You can also pass a block that'll be invoked if the retry attempts fail for custom logic rather than letting the exception bubble up. This block is yielded with the job instance as the first and the error instance as the second parameter.

Upvotes: 3

Lam Phan
Lam Phan

Reputation: 3811

I assume that you are testing ActiveJob, i guess retry_on will enqueue job instead of perform immediately, so you could try setup job queue using ActiveJob::TestHelper

your test case should be:

require 'rails_helper'
RSpec.describe CrawlSsbJob, type: :job do
 include ActiveJob::TestHelper
 before(:all) do
   ActiveJob::Base.queue_adapter = :test
 end

 it "retries the job if session error" do
   allow(Ssb::Client).to receive(:get_data).and_raise(Ssb::SessionExpired)
   expect(Ssb::Login).to receive(:call)
   # enqueue job
   perform_enqueued_jobs {
    described_class.perform_later # or perform_now
   end
 end
end

Upvotes: 0

Related Questions