Dans l'article [Ruby] Procédure de création d'une classe de liaison d'API externe à l'aide de faraday, nous avons présenté comment créer un lien avec une API externe à l'aide de faraday.
Dans le code de test logique qui utilise une API externe, il est courant de stuber les requêtes HTTP au lieu d'utiliser l'API réelle. Dans Rails, vous pouvez stuber les requêtes HTTP en utilisant un gem appelé webmock.
Cette fois, je vais vous présenter comment créer un code de test logique lié à une API externe à l'aide de WebMock.
Cette fois, nous allons créer un code de test pour une classe appelée QiitaClientAPI
qui fonctionne avec l'API Qiita.
La classe implémente une méthode appelée get_items
pour obtenir une liste d'articles de Qiita.
Le code source spécifique est le suivant.
lib/qiita_api_client.rb
class QiitaApiClient
class HTTPError < StandardError
def initialize(message)
super "connection failed: #{message}"
end
end
class << self
def connection
Faraday::Connection.new('https://qiita.com') do |builder|
builder.authorization :Bearer, "#{Rails.application.credentials.qiita[:token]}"
builder.request :url_encoded #Paramètres de demande de codage d'URL
builder.response :logger #Sortie de la réponse en standard
builder.adapter Faraday.default_adapter #Sélection de l'adaptateur. La valeur par défaut est Net::HTTP
builder.response :json, :content_type => "application/json" #JSON analyse le corps de la réponse
end
end
def get_items
begin
response = connection.get(
'/api/v2/items'
)
response.body
rescue Faraday::ConnectionFailed => e
raise QiitaApiClient::HTTPError.new(e.message)
end
end
end
end
Préparez-vous à exécuter le code de test.
Cette fois, nous utiliserons RSpec comme cadre de test. Ajoutez rspec-rails à votre Gemfile.
Gemfile
group :development, :test do
gem 'rspec-rails'
end
Installez gem et configurez RSpec.
$ bundle install
$ rails generate rspec:install
Ajoutez webmock à votre Gemfile et installez-le.
Gemfile
gem 'webmock'
$ bundle install
Ci-dessous, nous allons vous présenter comment écrire du code de test à l'aide de WebMock.
Le code de test pour le système normal est le suivant.
spec/lib/qiita_api_client_spec.rb
require 'rails_helper'
describe 'QiitaApiClient' do
before do
WebMock.enable! #Activer WebMock
allow(Rails.application.credentials).to receive(:qiita).and_return({token: '123'})
end
describe '.get_items' do
let(:response_body) { [{ "title": "test" }].to_json }
before do
WebMock.stub_request(:get, "https://qiita.com/api/v2/items").
with(
headers: {'Authorization' => "Bearer 123"}
).
to_return(
body: response_body,
status: 200,
headers: { 'Content-Type' => 'application/json' }
)
end
it 'Les données peuvent être obtenues' do
expect(QiitaApiClient.get_items).to eq(JSON.parse(response_body))
end
end
end
J'ai activé WebMock avec WebMock.enable!
Et créé un stub de requête HTTP à WebMock.stub_request
.
En utilisant WebMock, vous pouvez décrire le comportement de «quel type de requête est retourné et quel type de réponse est retourné». Cela vous permet de créer une situation simulée dans laquelle des données sont échangées via une API externe.
Pour allow (Rails.application.credentials)
décrit dans before
, définissez une valeur factice pour Rails.application.credentials.qiita [: token]
décrit dans le code de l'application. Est pour.
Si le code d'application ne peut pas communiquer normalement avec l'API externe, il lève l'exception QiitaApiClient :: HTTPError
avec un message d'erreur.
Le code de test du système anormal qui confirme qu'une exception s'est produite est le suivant.
spec/lib/qiita_api_client_spec.rb
require 'rails_helper'
describe 'QiitaApiClient' do
before do
WebMock.enable!
allow(Rails.application.credentials).to receive(:qiita).and_return({token: '123'})
end
describe '.get_items' do
let(:response_body) { { "message": "error_message", "type": "error_type" }.to_json }
before do
WebMock.stub_request(:get, "https://qiita.com/api/v2/items").
to_raise(Faraday::ConnectionFailed.new("some error"))
end
it 'Qu'une exception se produit' do
#Le test d'exception est attendu()Pas attendre{}Donc sois prudent
expect{QiitaApiClient.get_items}.to raise_error(QiitaApiClient::HTTPError, "connection failed: some error")
end
end
end
J'ai créé un stub qui lève une exception avec to_raise
dans WebMock et confirmé que l'exception est levée avec rise_error
dans expect.
Le code de test final qui résume le système normal et le système anormal introduit cette fois est le suivant.
spec/lib/qiita_api_client_spec.rb
require 'rails_helper'
describe 'QiitaApiClient' do
let(:qiita_base_uri) { 'https://qiita.com/api/v2' }
before do
WebMock.enable!
allow(Rails.application.credentials).to receive(:qiita).and_return({token: '123'})
end
describe '.get_items' do
subject { QiitaApiClient.get_items }
context 'Succès' do
let(:response_body) { [{ "title": "test" }].to_json }
before do
WebMock.stub_request(:get, "#{qiita_base_uri}/items").
with(
headers: {'Authorization' => "Bearer 123"}
).
to_return(
body: response_body,
status: 200,
headers: { 'Content-Type' => 'application/json' }
)
end
it 'Les données peuvent être obtenues' do
expect(subject).to eq(JSON.parse(response_body))
end
end
context 'Échec' do
before do
WebMock.stub_request(:get, "#{qiita_base_uri}/items").
to_raise(Faraday::ConnectionFailed.new("some error"))
end
it 'Qu'une exception se produit' do
expect{subject}.to raise_error(QiitaApiClient::HTTPError, "connection failed: some error")
end
end
end
end
Nous présenterons comment utiliser WebMock pour créer du code de test pour la logique liée à une API externe.
Le flux du code de test à l'aide de WebMock est le suivant.
Je fais Twitter (@ nishina555). J'espère que vous me suivrez!
Recommended Posts