[RUBY] [RSpec] Verwenden Sie WebMock, um die Logik mithilfe einer externen API zu testen

In dem Artikel [Ruby] Verfahren zum Erstellen einer externen API-Verknüpfungsklasse mit Faraday wurde die Verknüpfung mit einer externen API mithilfe von Faraday vorgestellt.

In logischem Testcode, der eine externe API verwendet, werden häufig HTTP-Anforderungen gestoppt, anstatt die eigentliche API zu verwenden. In Rails können Sie HTTP-Anforderungen mithilfe eines Gems namens webmock stubben.

Dieses Mal werde ich vorstellen, wie mit WebMock ein logischer Testcode erstellt wird, der mit einer externen API verknüpft ist.

Die Zielklasse des Testcodes

Dieses Mal erstellen wir einen Testcode für eine Klasse namens "QiitaClientAPI", die mit der Qiita-API funktioniert. Die Klasse implementiert eine Methode namens "get_items", um eine Liste von Artikeln aus Qiita abzurufen.

Der spezifische Quellcode lautet wie folgt.

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 #Anforderungsparameter für die URL-Codierung
        builder.response :logger #Geben Sie die Antwort standardmäßig aus
        builder.adapter Faraday.default_adapter #Adapterauswahl. Der Standardwert ist Net::HTTP
        builder.response :json, :content_type => "application/json" #JSON analysiert den Antworttext
      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

Vorbereitung

Bereiten Sie die Ausführung des Testcodes vor.

RSpec-Setup

Dieses Mal werden wir RSpec als Testframework verwenden. Fügen Sie rspec-Rails zu Ihrer Gemfile hinzu.

Gemfile


group :development, :test do
  gem 'rspec-rails'
end

Installieren Sie gem und richten Sie RSpec ein.

$ bundle install
$ rails generate rspec:install

Webmock installieren

Fügen Sie webmock zu Ihrer Gemfile hinzu und installieren Sie es.

Gemfile


gem 'webmock'
$ bundle install

Implementierung von Testcode

Im Folgenden wird erläutert, wie Sie Testcode mit WebMock schreiben.

Normaler Systemtest

Der Testcode für das normale System lautet wie folgt.

spec/lib/qiita_api_client_spec.rb


require 'rails_helper'

describe 'QiitaApiClient' do
  before do
    WebMock.enable! #Aktivieren Sie 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 'Daten können erhalten werden' do
      expect(QiitaApiClient.get_items).to eq(JSON.parse(response_body))
    end
  end
end

Ich habe WebMock mit "WebMock.enable!" Aktiviert und einen HTTP-Anforderungsstub unter "WebMock.stub_request" erstellt.

Mithilfe von WebMock können Sie das Verhalten von "Welche Art von Anforderung wird zurückgegeben und welche Art von Antwort wird zurückgegeben" beschreiben. Auf diese Weise können Sie eine simulierte Situation erstellen, in der Daten über eine externe API ausgetauscht werden.

Legen Sie für "allow (Rails.application.credentials)", wie in "before" beschrieben, einen Dummy-Wert für "Rails.application.credentials.qiita [: token]" fest, der im Anwendungscode beschrieben ist. Ist für.

Abnormaler Systemtest (Auftreten von Ausnahmen)

Wenn der Anwendungscode nicht normal mit der externen API kommunizieren kann, wird die Ausnahme "QiitaApiClient :: HTTPError" mit einer Fehlermeldung ausgelöst.

Der Testcode für das abnormale System, der bestätigt, dass eine Ausnahme aufgetreten ist, lautet wie folgt.

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 'Dass eine Ausnahme auftritt' do
      #Ausnahmetest wird erwartet()Nicht erwartet{}Also sei vorsichtig
      expect{QiitaApiClient.get_items}.to raise_error(QiitaApiClient::HTTPError, "connection failed: some error")
    end
  end
end

Ich habe einen Stub erstellt, der eine Ausnahme mit "to_raise" in WebMock auslöst, und bestätigt, dass die Ausnahme mit "raise_error" in Erwartung ausgelöst wird.

Endgültiger Testcode

Der endgültige Testcode, der das diesmal eingeführte normale System und das abnormale System zusammenfasst, lautet wie folgt.

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 'Erfolg' 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 'Daten können erhalten werden' do
        expect(subject).to eq(JSON.parse(response_body))
      end
    end
    context 'Fehler' do
      before do
        WebMock.stub_request(:get, "#{qiita_base_uri}/items").
          to_raise(Faraday::ConnectionFailed.new("some error"))
      end
      it 'Dass eine Ausnahme auftritt' do
        expect{subject}.to raise_error(QiitaApiClient::HTTPError, "connection failed: some error")
      end
    end
  end
end

Zusammenfassung

Wir werden vorstellen, wie Sie mit WebMock Testcode für Logik erstellen, die mit einer externen API verknüpft ist.

Der Ablauf des Testcodes mit WebMock ist wie folgt.

  1. Aktivieren Sie WebMock mit Webmock.enable!
  2. Erstellen Sie einen HTTP-Anforderungsstub mit WebMock.stub_request
  3. Führen Sie die Methode aus, die die externe API verwendet, und überprüfen Sie das Ausführungsergebnis.

Ich mache Twitter (@ nishina555). Ich hoffe du folgst mir!

Recommended Posts

[RSpec] Verwenden Sie WebMock, um die Logik mithilfe einer externen API zu testen
Verwenden Sie Webmock mit Rspec
Verwendung der Ketten-API
Zeigen Sie die Wettervorhersage mit OpenWeatherMap an, einer externen API in Ruby
[Rails] Testcode mit Rspec
Testen Sie das Verhalten des Protokollausgabeprotokollierers, wenn Sie eine externe Protokollierungs-API wie SLF4J verwenden
Bild-Upload mit CarrierWave ~ Rspec-Test ~
So fügen Sie eine externe Bibliothek ein
[RSpec] Unit Test (mit gem: factory_bot)
[Für Rails-Anfänger] Zusammenfassung der Verwendung von RSpec (Überblick)
Java Artery - Einfach zu verwendende Unit-Test-Bibliothek
[Docker] Erstellen einer Umgebung für Hugo
So spielen Sie eine MIDI-Datei mit der Java Sound API ab (geben Sie das zu verwendende MIDI-Gerät an)