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) David Chelimsky, Dave Astels, Zach Dennis, 角谷 信太郎, 豊田 祐司, 株式会社クイープ |
Appendix
Railsでwebmockを導入すると、初期設定ではすべての外部アクセスを遮断してしまうので、
config/environments/development.rbに以下を追加して外部アクセスできるようにしておけばいつもどおり利用できます。
WebMock.allow_net_connect!(:net_http_connect_on_start => true)