Search code examples
ruby-on-railsrubyvcrruby-test

How make stub on request with VCR?


How can I do stub on request with VCR?

The problem is that real request is made in the test, which I want to stub.

RSpec.describe CreditRegisterLoader do
  describe ".call" do
    it "should create credit institutions", :vcr do
      Timecop.freeze(2020, 3, 25, 13, 0, 0) do
        expect { described_class.new.call }.to change { CreditInstitution.count }.by(4965)
      end
    end
  end
end

Also here is code of my class CreditRegisterLoader which I want to test:

class CreditRegisterLoader < ApplicationService
  def initialize
    @timestamp = (Time.now - 1.minute).to_i.to_s
  end

  def call
    sai_response = get_credit_institutions
    unless sai_response
      Airbrake.notify("invalid_sai_response")
      return
    end

    begin
      CreditInstitutionUpdater.new(JSON.parse(sai_response.body)).create
    rescue => error
      Airbrake.notify(error)
    end
  end

private

  def get_credit_institutions
    RestClient::Request.execute(
      method:  :post,
      url:     "https://sai.dpl.europa.eu/register/api/search/entities?t=#{@timestamp}",
      headers: {
        "Content-Type" => "application/json",
        "Accept"       => "application/json",
      },
      payload: JSON.generate({"$and": [{"_messagetype": "SAIDPL"}]})
    )
  end
end

Solution

  • I would suggest the following solution

    RSpec.describe CreditRegisterLoader do
      describe ".call" do
        let(:response) { OpenStruct.new(body: File.read("yours fixtures in json format")) }
    
        context "Failure flow" do
          it "should notify Airbrake with error" do
            error = StandardError.new("Bad Request")
    
            expect(RestClient::Request).to receive(:execute).and_return(response)
            expect_any_instance_of(CreditInstitutionUpdater).to receive(:create).and_raise(error)
    
            expect(Airbrake).to receive(:notify).with(error)
    
            subject.call
          end
    
          it "should notify Airbrake with invalid_sai_response" do
            expect(subject).to receive(:get_credit_institutions).and_return(nil)
            expect(Airbrake).to receive(:notify).with("invalid_sai_response")
    
            subject.call
          end
        end
    
        context "Successfully flow" do
          it "should creates credit institutions" do
            expect(RestClient::Request).to receive(:execute).and_return(response)
    
            expect { subject.call }.to change { CreditInstitution.count }.by(2)
    
            fixtures_response = JSON.parse(response.body)
          end
        end
      end
    end