1

I created a simple ruby file (not Rails) and I am trying to test (using Rspec) a method where I am calling an API. In the test I am trying to mock the call via WebMock but it keeps giving me this error:

Requests::FilesManager#display fetches the files from the API
     Failure/Error: Requests::FilesManager.new.display
     
     ArgumentError:
       wrong number of arguments (given 2, expected 1)

The files are:

#run.rb
module Requests
  require "httparty"
  require 'json'

  class FilesManager
      include HTTParty

      def initialize

      end

      def display
        response = HTTParty.get('https://api.publicapis.org/entries', format: :json)
        parsed_response = JSON.parse(response.body)
        puts "The secret message was: #{parsed_response["message"]}"
      end
  end
end

and the spec file:

require 'spec_helper'
require_relative '../run'

RSpec.describe Requests::FilesManager do
  describe "#display" do
    it 'fetches the files from the API' do
      stub_request(:get, "https://api.publicapis.org/entries").
        to_return(status: 200, body: "", headers: {})

      Requests::FilesManager.new.display
    end
  end
end

EDIT: So the error seems to come from the line:

JSON.parse(response.body)

If I comment it out it disappears. The problem then is that the output of the call is not a json (even with the format: :json when calling the HTTParty). I tried other solutions but nothing seems to work in making the response json. It is just a string.

josegp
  • 499
  • 6
  • 21
  • The problem is not with the mock but in this line: `Requests::MyCLI.new.display_files`. What does `Requests::MyCLI` look like and how are its `initialize` and `display_files` methods defined? – spickermann Sep 19 '22 at 05:26
  • Thank for the reply. Apologies, I updated the error @spickermann. Any ideas why it is failing? – josegp Sep 19 '22 at 05:55

4 Answers4

1

Change

response = HTTParty.get('https://api.publicapis.org/entries', format: :json)

to

response = HTTParty.get('https://api.publicapis.org/entries').

I think you don't need the format: :json more so when you explicitly format the response to JSON anyway.

emi
  • 2,830
  • 5
  • 31
  • 53
1

You need to return a json object in the body parameter of the stubbed response:

E.g: For an empty response:

  stub_request(:get, "https://api.publicapis.org/entries").
    to_return(status: 200, body: "".to_json, headers: {})

OR For a valid response: (Note: You may have to require json to convert a hash to json)

require 'json'
...

  stub_request(:get, "https://api.publicapis.org/entries").
    to_return(status: 200, body:  { entries: { '0': { message: "Hello World" } } }.to_json, headers: {})
1

Solved!

  1. It seems there was an error because the json gem version that HTTParty uses is too old.

  2. Moved on to RestClient gem for the RESTful API calls. It had another conflict in the mime gem versioning.

  3. Finally moved to Faraday and that solved my problems:

JSON.parse(response.body, :quirks_mode => true)
josegp
  • 499
  • 6
  • 21
1

tl;dr Had the same issue and ended up having to upgrade webmock.

Long form:

Webmock inserts middleware into your calls, so when HTTParty makes the calls they end up going through the Webmock interfaces first.

You can verify this by trying the call standalone (withouth all the rspec config):

bundle console
irb> require "httparty"
=> true
irb> httparty.get("https://google.com")

If that standalone call succeeds, the issue is somewhere within Webmock itself.

For me, somewhere along the line of calls through Webmock was an outdated interface that was incompatible and throwing the Wrong Number of Arguments error. And this was also crashing my debugger (RubyMine).

Upgrading Webmock solved this issue (because they had fixed it in newer versions).

Andrei
  • 2,282
  • 26
  • 35
  • If this is not the case, let me know and I will remove the answer to not confuse people. – Andrei Nov 09 '22 at 06:39
  • 1
    Thanks @Andrei, my bad I already found out the answer a while ago but didn't mark it as solved. I see no issue in leaving your answer here though! It will be valuable for other people for sure – josegp Nov 12 '22 at 02:10