0

I've created the following service

class ApiCustomers < ApiBase
  def initialize(url: nill)
    url = url.presence || ENV.fetch("CUSTOMERS_API_APP_NAME")
    super(url)
  end

  def find_customer_apps(customer_id, params=nil)
    begin
      customer_url = "#{@url}/customers/#{customer_id}/applications"
      # call api-customers
      if params.nil?
        response = connection.get(customer_url)
      else
        response = connection.get(customer_url, params)
      end
    rescue StandardError => e
      Rails.logger.error "Error fetching API-CUSTOMERS Applications: #{e}"
      raise e
    end

    return response.body["data"]
  end
end

Now, I want to test that with the following code:

require "rails_helper"

RSpec.describe ApiCustomers do
  let(:customer_id) { SecureRandom.uuid }
  let(:customers_client) { ApiCustomers.new(url: "api_customers.local") }

  context "#find_customer_apps" do
    let(:app) { double("application", id: 123, name: "App", customer_id: "123", supported: false, additional_notes: "Test") }
    let(:success_response) { OpenStruct.new({ status: 200, body: { "data": app } }) }
    let(:bad_request) { OpenStruct.new({ status: 400, body: {"error"=>"invalid call"} }) }

    describe "with valid params" do
      before do
        allow_any_instance_of(Faraday::Connection).to receive(:get).and_return(success_response)
      end

      it "returns customer applications" do
        applications_payload = customers_client.find_customer_apps(account_id, nil)


        expect(applications_payload).not_to be_nil
      end
    end

    describe "with invalid params" do
      before do
        allow_any_instance_of(Faraday::Connection).to receive(:get).and_raise(CustomErrors::BadRequest)
      end

      it "raises an error" do
        expect { customers_client.find_customer_apps(nil, nil) }.to raise_error(CustomErrors::BadRequest)
      end
    end
  end
end

The test with invalid params is working, but for some reason the one with valid params is failing.

If I print the success_response, this is being created properly. I do not know what I am getting nil in my applications_paylod. What I am missing? I thought this line should cover what I am doing: allow_any_instance_of(Faraday::Connection).to receive(:get).and_return(success_response)

Thanks in advance.

RubyLearning
  • 83
  • 1
  • 7
  • Before this line `expect(applications_payload).not_to be_nil` what's the value of `applications_payload` ? – brcebn Feb 23 '22 at 14:29
  • I would suggest to **never** use `allow_any_instance_of` since you don't really know what you're stubbing and how many times you're doing it. You should take a look at [webmock](https://github.com/bblimke/webmock) to avoid that. – brcebn Feb 23 '22 at 14:31
  • well, I thought the value was the stub created and instanced on the before method, but I will read about the webmock link you sahred @brcebn. Thanks a lot – RubyLearning Feb 23 '22 at 14:43
  • Maybe it is not your issue (and it will not solve the problem) but I would suggest not to use variable `app` - you can get "funny" behavior. See https://stackoverflow.com/questions/30455670/cannot-make-rails-spec-for-a-request-working-undefined-method-call-for-ap/30457563#30457563 – gotva Feb 23 '22 at 17:30

1 Answers1

0

I found the issue:

In my stub:

let(:success_response) { OpenStruct.new({ status: 200, body: { "data": app } }) }

I am creating an Struct, so, I decided to change the code of my method in order to return: response.body[:data]

instead of response.body["data"]

RubyLearning
  • 83
  • 1
  • 7