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