webmockとvcrを利用してHTTPのmockを作成する

Ruby

RubyGems

RubyやRailsで外部APIを利用するソフトウェアを開発しているときに、テストで実際に何度もAPIに問い合わせにをしていたら、遅くて話になりません。ましてや、外部APIがメンテナンスなんてことになったら、開発が止まってしまいます。

そこで、webmockなどを利用して、HTTPリクエストやレスポンスのmockを作成することが望ましいです。

vcrを組み合わせて利用すれば、初回だけ実際にHTTPリクエストとレスポンスを記録して、2回目以降は記録したデータからmockとしてデータを返すように簡単にできます。

スポンサーリンク

webmockとvcrのインストール方法

Gemfileに以下のように記述する

group :development, :test do
  gem 'webmock'
  gem 'vcr'
end

gemをインストールする

$ bundle

test/test_helper.rbにVCRに関する設定を追加する

VCR.configure do |c|
    c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
    c.hook_into :webmock
end

やってることは

  • VCRで記録するデータをYAML形式で保存するディレクトリを指定
  • webmockをhookとする

VCRの利用方法

例えばGitHubのAPIを簡単に利用できるoctokitを利用する場合、内部でHTTPリクエストを作成して、JSONデータを取得している。

よって、VCR.use_cassetteのブロックの中で、Octocatを利用する。

require 'octokit'
VCR.use_cassette('user_octokit') do
    Octokit.user 'octokit'
end

こうすると、初回のOctokit.user実行時にリクエストとレスポンスがspec/fixtures/vcr_cassettes/user_octokit.ymlに以下のように記録される。

---
http_interactions:
- request:
    method: get
    uri: https://api.github.com/users/octokit
    body:
      encoding: US-ASCII
      string: ''
    headers:
      User-Agent:
      - Octokit Ruby Gem 1.23.0
      Accept:
      - application/vnd.github.beta+json
      Accept-Encoding:
      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
  response:
    status:
      code: 200
      message: !binary |-
        T0s=
..... 省略 .....

2回目以降の実行では実際にHTTPリクエストを発行せずに、YAMLのデータからレスポンスを返すようになります。

The RSpec Book (Professional Ruby Series)

The RSpec Book (Professional Ruby Series)

David Chelimsky, Dave Astels, Zach Dennis, 角谷 信太郎, 豊田 祐司, 株式会社クイープ

Appendix

Railsでwebmockを導入すると、初期設定ではすべての外部アクセスを遮断してしまうので、

config/environments/development.rbに以下を追加して外部アクセスできるようにしておけばいつもどおり利用できます。

WebMock.allow_net_connect!(:net_http_connect_on_start => true)
タイトルとURLをコピーしました