dwa*_*h91 9 ruby rspec httparty
我正在使用 HTTParty gem 调用 GitHub API 以访问用户的存储库列表。
这是一个使用 Sinatra 的非常简单的应用程序,它根据用户存储库中出现的最常用语言显示用户最喜欢的编程语言。
我对如何编写一个模拟实际 API 调用的 RSpec 期望值有点困惑,而只是检查是否正在返回 json 数据。
我有一个模拟 .json 文件,但不确定如何在我的测试中使用它。
有任何想法吗?
github_api.rb
require 'httparty'
class GithubApi
attr_reader :username, :data, :languages
def initialize(username)
@username = username
@response = HTTParty.get("https://api.github.com/users/#{@username}/repos")
@data = JSON.parse(@response.body)
end
end
Run Code Online (Sandbox Code Playgroud)
github_api_spec.rb
require './app/models/github_api'
require 'spec_helper'
describe GithubApi do
let(:github_api) { GithubApi.new('mock_user') }
it "receives a json response" do
end
end
Run Code Online (Sandbox Code Playgroud)
为清楚起见,其余文件:
结果.rb
require 'httparty'
require_relative 'github_api'
class Results
def initialize(github_api = Github.new(username))
@github_api = github_api
@languages = []
end
def get_languages
@github_api.data.each do |repo|
@languages << repo["language"]
end
end
def favourite_language
get_languages
@languages.group_by(&:itself).values.max_by(&:size).first
end
end
Run Code Online (Sandbox Code Playgroud)
应用控制器.rb
require './config/environment'
require 'sinatra/base'
require './app/models/github_api'
class ApplicationController < Sinatra::Base
configure do
enable :sessions
set :session_secret, "@3x!ilt£"
set :views, 'app/views'
end
get "/" do
erb :index
end
post "/user" do
@github = GithubApi.new(params[:username])
@results = Results.new(@github)
@language = @results.favourite_language
session[:language] = @language
session[:username] = params[:username]
redirect '/results'
end
get "/results" do
@language = session[:language]
@username = session[:username]
erb :results
end
run! if app_file == $0
end
Run Code Online (Sandbox Code Playgroud)
ari*_*ver 11
有多种方法可以解决这个问题。
正如@anil 建议的那样,您可以使用像 webmock 这样的库来模拟底层的 HTTP 调用。您还可以使用 VCR ( 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(response.body)
end
end
end
Run Code Online (Sandbox Code Playgroud)
请注意,您不需要@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
Run Code Online (Sandbox Code Playgroud)
请注意,不需要实际加载或解析任何真正的 JSON。我们在这里测试的是我们进行了正确的 HTTP 调用并且我们调用JSON.parse
了响应。一旦开始测试该languages
方法,您就需要实际加载和解析您的测试文件,如下所示:
let(:parsed_response) { JSON.parse(File.read('path/to/test/file.json')) }
Run Code Online (Sandbox Code Playgroud)