Существует несколько способов решения этой проблемы.
Вы можете, как предложил @anil, использовать такую библиотеку, как webmock, чтобы высмеивать основной HTTP-вызов.Вы также делаете нечто подобное с видеомагнитофоном (https://github.com/vcr/vcr), который записывает результаты фактического вызова конечной точки HTTP и воспроизводит этот ответ при последующих запросах.
Но, учитывая ваш вопрос, я неЯ не понимаю, почему вы не можете просто использовать Rspec double. Я покажу вам, как это показано ниже. Но, во-первых, было бы немного проще протестировать код, если бы он не был все в конструкторе.
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(repos.body)
end
end
end
Обратите внимание, что вам не нужно ссылаться на переменную @username
в URL, потому что у вас есть 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
Обратите внимание, что на самом деле нет необходимости загружать или анализировать какой-либо настоящий JSON. Мы тестируем здесь то, что мы сделали правильный HTTP-вызов и что мы вызвали JSON.parse
в ответе. Как только вы начнете тестировать метод languages
, вам нужно будет на самом деле загрузить и проанализировать ваш тестовый файл, например так:
let(:parsed_response) { JSON.parse(File.read('path/to/test/file.json)) }