前提
以下のような背景から、外部APIのテストにはモックやスタブを使うのが一般的。
- 現在、自前アプリに外部APIを組み込んで機能開発することが一般的
↓ - 外部APIは従量課金のものが多いが、テストはどうするか
↓ - RSpec実行のたびに外部APIを叩くのはコストが無駄
- かつ、外部APIのロジックは提供元が担保するので、そもそも叩く必要性は薄い
↓ - モック・スタブを使うことで、あたかも外部APIを叩いた体でレスポンスデータ(固定値)を返してくれる
↓ - 開発者はデータ返却後の後続のテストを書けば良い
例
Faraday.newでconnectionオブジェクトを作成し、
connection.postでHTTPリクエスト(POST)を発行するAPIの例。
モック
- APIレスポンスの代わりに返すオブジェクト
# ex
connection = double
#=> ダミーのオブジェクトをconnectionに代入しておく
スタブ
- APIリクエストなどの代わりに実行するメソッド
# ex
allow(Faraday).to receive(:new).and_return(connection)
#=> Faraday.new すると connection が返却されるように処理を変えるということ
allow(connection).to receive(:post) { Faraday::Response.new(status: 400) }
#=> connection.new すると Faraday::Response が返却されるように処理を変えるということ
挙動
-
アプリケーション本来の動き
- Faraday.newすると、connection(APIクライアント)が返却される
- connection.postすると、Faraday::Responseオブジェクト(HTTPリクエストの結果)が返却される
-
specでの動き
- Faraday.newすると、connection(モック)が返却される
- connection.postすると、Faraday::Responseオブジェクト(400)が返却される
まとめ
- モックとスタブを利用し、返却するオブジェクトを固定しておくことで、あたかもAPIリクエストを発行したかのようにテストすることができる
- 正しいリクエストならば正しいレスポンスが返却される前提があるので、そこはAPI提供元に委ねる、その代わりレスポンスを得た後のアプリケーションの挙動を検証する、という考え方が基本
参考