Elixirで外部API呼び出しのテストをする

elixir-flame-i-catch

外部APIを呼び出すアプリケーションをテストする場合、テストのたびにリクエストを送信するのは現実的ではありませんが自作のレスポンスデータを使うと、バグをテストで発見できなくなってしまう場合があります。
できる限り本物のAPIレスポンスを使ってテストしたいです。
Elixirにはexvcrというライブラリを使うことで本物のAPIレスポンスを使ったテストが簡単に実現できます。今回はexvcrを使って外部API呼び出しのテストを書いてみます。

インストール

サンプルプロジェクトを作成し、mix.exsファイルに以下の記述を追加してインストールします。
環境構築、プロジェクトの作成方法はこのページを参照してください
MacにElixir環境を構築する

  defp deps do
    [
      {:exvcr, "~> 0.6", only: :test}, # この行を追加します
    ]
  end

以下のコマンドでインストールします

mix deps.get

テストコード

今回はGitHub APIを呼び出すアプリケーションを例にテストしてみます(テスト対象のライブラリ)。
exvcrは最初、実際にAPIをコールして返却された値をJSONに保存し、2回目以降はそのJSONの値をレスポンスとして使用します。

設定

まずtest_helper.exsファイルにJSONの保存先ディレクトリを指定します

ExUnit.start()

ExVCR.Config.cassette_library_dir("test/fixture/vcr_cassettes") # この行を追加

テストコードの作成

テストコードを書きます。テスト対象はEhee.Gistsモジュールのlistメソッドです。

defmodule Ehee.GistsTest do
  use ExUnit.Case, async: false
  use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney # この行を追加
  import Ehee.Gists

  @credential Ehee.Credential.new(%{access_token: "yourtokencomeshere"})

  setup_all do
    HTTPoison.start
  end

  test "list" do
    use_cassette "gists#list" do # テストコードをブロックで囲む
      all_gists = list(@credential)
      assert Enum.count(all_gists) > 1
    end
  end

レスポンスデータの作成

テストを実施します。

mix test

テストを実施するとproject_root/test/fixture/vcr_cassetesディレクトリの下にgists#list.jsonが作成されました。
次回以降のテストではこのjsonファイルの内容がレスポンスとして使用されます。

  • gists#list.jsonの中身
[
  {
    "request": {
      "body": "\"\"",
      "headers": {
        "Authorization": "token yourtokencomeshere"
      },
      "method": "get",
      "options": [],
      "request_body": "",
      "url": "https://api.github.com/gists"
    },
    "response": {
      "body": "[{\"url\":\"https://api.github.com/gists/xxxxxx\", ....}]",
    "headers": {
        "Server": "GitHub.com",
        "Date": "Sun, 02 Oct 2016 07:41:45 GMT",
        "Content-Type": "application/json; charset=utf-8",
        "Content-Length": "8413",
        "Status": "200 OK",
        .....
      },
      "status_code": 200,
      "type": "ok"
    }
  }
]

まとめ

テストコードが書きやすいのはElixirの魅力の一つですが、このライブラリを使うことでより簡単にテストをすることができます。
これ以外にもどのようなテストライブラリがあるか探ってみて、良いものがあればまた紹介します。

AWS Cloud Roadshow 2017 福岡