リクエスト spec を書こう - satococoa/api-tutorial GitHub Wiki
リクエスト spec とは
主に API のテストに使われ、「このパスにこのパラメータ、データを持ってアクセスするとこういう出力が得られる」という一連のアプリケーションの特定のパスの入出力を試験します。
投稿一覧の取得を前回作りましたので、それをテストしてみたいと思います。 テストの中身は以下のような感じです。
- 投稿が 10 個あるとき
- 投稿一覧のパスに GET で json をリクエストしたとき
- ステータスコードは 200 が返る
- 10 個の投稿の内容 (title, name, body) が json で返ってくる
以下のコマンドで request spec のひな形を generate してください。
rails generate integration_test api/v1/posts
生成された spec/requests/api/v1/api_v1_posts_spec.rb を以下のように編集します。
require 'spec_helper'
describe "Api::V1::Posts" do
describe "GET /api/v1/posts" do
before do
10.times { FactoryGirl.create(:post) }
end
it 'レスポンスコードは 200' do
get api_v1_posts_path, format: :json
expect(response.status).to eq(200)
end
it '10個の投稿が返る' do
get api_v1_posts_path, format: :json
json = JSON.parse(response.body)
expect(json.count).to eq(10)
end
it '各要素は title, name, body 属性を持つ' do
get api_v1_posts_path, format: :json
json = JSON.parse(response.body)
json.each do |data|
keys = data.keys
expect(keys).to match_array(['title', 'name', 'body'])
end
end
end
end
例)
it '必要な属性がある' do
get api_v1_posts_path, format: :json
json = JSON.parse(response.body)
json.each do |data|
expect(data.keys).to match_array(['title', 'name', 'body'])
#expect(data['title']).not_to eq('')
#expect(data['body']).not_to eq('')
#expect(data['name']).not_to eq('')
#expect(data['title'].nil?).not_to be_true
#expect(data['body'].nil?).not_to be_true
#expect(data['name'].nil?).not_to be_true
end
end
テストコードを rake spec
コマンドで実行してください。すべてのテストがパスすれば成功です。
リファクタリング
実装コードは十分すぎるほどシンプルなので、テストコードの方をリファクタリングしてみます。 spec/requests/api/v1/api_v1_posts_spec.rb は以下のようになりました。
require 'spec_helper'
describe "Api::V1::Posts" do
describe "GET /api/v1/posts" do
context '10 個の投稿があるとき' do
subject(:json) { JSON.parse(response.body) }
before do
10.times { FactoryGirl.create(:post) }
get api_v1_posts_path, format: :json
end
it "レスポンスコードは 200" do
expect(response.status).to eq(200)
end
it "10 個の投稿が返る" do
expect(json).to have(10).posts
end
it "各要素は title, name, body 属性を持つ" do
json.each do |data|
expect(data.keys).to match_array(['title', 'name', 'body'])
end
end
end
end
end
注意
本来は前回の Api::V1::PostsController#index を実装する前にこの spec から書くべきではありましたが、わかりやすくするためにこの順序で書きました。