Solución:
Hay varias formas de abordar este problema.
Como sugirió @anil, podría usar una biblioteca como webmock para simular la llamada HTTP subyacente. También puede hacer algo similar con VCR (https://github.com/vcr/vcr) que registra los resultados de una llamada real al extremo HTTP y reproduce esa respuesta en solicitudes posteriores.
Pero, dada su pregunta, no veo por qué no podría usar un doble Rspec. Te mostraré cómo a continuación. Pero, primero, sería un poco más fácil probar el código si no estuviera todo en el constructor.
github_api.rb
require 'httparty'
class GithubApi
attr_reader :username
def initialize(username)
@username = username
end
def favorite_language
# method to calculate which language is used most by username
end
def languages
# method to grab languages from repos
end
def repos
repos ||= do
response = HTTParty.get("https://api.github.com/users/#{username}/repos")
JSON.parse(response.body)
end
end
end
Tenga en cuenta que no necesita hacer referencia al @username
variable en la URL porque tiene una attr_reader
.
github_api_spec.rb
require './app/models/github_api'
require 'spec_helper'
describe GithubApi do
subject(:api) { described_class.new(username) }
let(:username) { 'username' }
describe '#repos' do
let(:github_url) { "https://api.github.com/users/#{username}/repos" }
let(:github_response) { instance_double(HTTParty::Response, body: github_response_body) }
let(:github_response_body) { 'response_body' }
before do
allow(HTTParty).to receive(:get).and_return(github_response)
allow(JSON).to receive(:parse)
api.repos
end
it 'fetches the repos from Github api' do
expect(HTTParty).to have_received(:get).with(github_url)
end
it 'parses the Github response' do
expect(JSON).to have_received(:parse).with(github_response_body)
end
end
end
Tenga en cuenta que no es necesario cargar ni analizar ningún JSON real. Lo que estamos probando aquí es que hicimos la llamada HTTP correcta y que llamamos JSON.parse
en la respuesta. Una vez que empiece a probar el languages
método que necesitaría para cargar y analizar su archivo de prueba, como este:
let(:parsed_response) { JSON.parse(File.read('path/to/test/file.json)) }
Puede simular esas llamadas API usando https://github.com/bblimke/webmock y enviar mock.json usando webmock. Esta publicación, https://robots.thoughtbot.com/how-to-stub-external-services-in-tests lo guía a través de la configuración de webmock con RSpec (las pruebas en la llamada a la API de GitHub post mock también)