Tech Sketch Bucket of Technical Chips by TIS Inc.

RSpec Tips -- httpアクセスをスタブ化しよう --

Pocket

この記事はeXcale Developer's Blogから移転されたものです。


eXcale 開発チームの泉谷です。
今回は、httpアクセスをスタブ化するのに便利なWebMockを紹介します。
httpアクセスを伴う機能のテストで、実際にアクセスしたくない場合があると思います。
その際、自分でスタブ化することでも解決できますが、WebMockを使うことで簡潔に書くことができます。


eXcaleでは期間限定でサインアップキャンペーン実施中です。
キャンペーンは3月末で終了となります。まだサインアップしていない方は、この機会に是非サインアップしてみてください。
キャンペーン内容についてはこちらを参照してください。


WebMockとは

WebMockはRubyのテストの際、httpアクセスを簡単にスタブ化することができるライブラリです。
本記事ではRSpecと組み合わせて使う例を紹介しますが、RSpec以外にも対応しています。
詳細な使い方やソースコードはguthubで見ることができます。

準備

Gemfile に下記の通り test グループを追加し bundle install を実施してください。

準備が完了したら、実際にテストコードを書いていきましょう。

WebMockを使ったテスト

今回は与えられたURLにアクセスして、レスポンスコードに応じてメッセージを返すだけの簡単なメソッドを用意して、それをテストしてみます。

まずはテスト対象メソッドです。

テストコードはこんな感じにしてみました。

7行目でWebMockを使ってhttpアクセスをスタブ化しています。
stub_requestは、

のようにします。
アクセス先パスには正規表現を使うことも可能です。

このテストケースではステータスコードが200ではなかった場合のテストがありません。
コンテキストを追加したテストは以下のようになります。

このようにto_returnの内容を変えれば、その時々で返す値を変更できます。

応用的な使い方

・リクエストで渡す値によって返ってくる値を変える
例えばpostで送るデータによって返ってくる値が変わる場合、以下のようにwithを指定することで、リクエストデータとそれに対する返り値を指定できます。

・例外を発生させる
アクセス時に例外を発生させるには以下のようにします。

また、タイムアウトを発生させるto_timeoutというものもあります。
eXcaleではタイムアウトが発生した際のテストのために以下のようにスタブ化しています。


WebMockを使うときの注意点

WebMockをrequireした瞬間から、スタブ化していない普通のwebアクセスができなくなります。
実際にやってみましょう。
始めに例として紹介したテストコードで、WebMockでスタブ化した行をコメントアウトして実行してみます。

スタブ化しない場合でもwww.excale.netは実在するサイトなので、普通にアクセスして200が返るはずですが以下のようなエラーとなります。

WebMockのNetConnectNotAllowedErrorが発生しているのがわかります。
このように、WebMockを使う際、デフォルトではスタブ化していないアクセスは許可されていません。
このエラーを起きないようにして、スタブ化していないアクセスを許可するには以下の行をどこかに入れてください。(通常はspec_helperを用意してそこに書くと良いと思います。)

特に、複数のテストを同時に読み込んで実行する際など、WebMockを使っていないはずなのにアクセスできない!となる時があるので注意が必要です。


最後に

今回は、httpアクセスをスタブ化するWebMockを紹介しました。
WebMockを使えばhttpアクセスを含む機能が楽にテストできるようになります。
httpアクセスのスタブ化は、httpのアクセス先に変更があってもテストが通ってしまうというリスクがあるものの、
エラー発生時などテストしづらい場合の動作を確認するために有効です。
機会があればぜひ使ってみてください。

エンジニア採用中!私たちと一緒に働いてみませんか?