最近やたらとAPIを書くことが多いので、一旦自分の整理も含め、テスト周りの基本的なところについて書こうと思いました。
環境
- Ruby 2.2.0
- Rails 4.2.3
- RSpec 3.3.2
- Guard
- FactoryGirl
RSpec,Guard,FactoryGirlのインストール・使い方に関しては、あらかじめ「RailsでRspecを使用するための準備など」を読んで用意しておいてください。
RspecでAPIのテストを行う
RspecでAPIのテストを行う際には、通常のControllerテストではなく、Request specという機能を使用します。
Request specでテストを行う場合は、specフォルダ以下にrequestsフォルダを作成し、その下にspecファイルを作成していきます。
準備
specファイルの作成
はじめにspecファイルを作成していきます。今回はUserというModelに関連するAPIのテストを行う前提で進めていきます。
~ bundle exec rails g rspec:integration User
create spec/requests/users_spec.rb
FactoryGirlでテストデータの生成
今回はテストデータをFactoryGirlで作成してテストを行います。
spec/factoriesフォルダを作成し、user.rbを作ります。
FactoryGirl.define do
factory :user do
username "hoge"
display_name "hoge fuga"
email "hogehoge@fugafuga.com"
password "qita"
end
end
Guardの起動
自動でテストが実行されるようにGuardを起動しておきます。
Railsのアプリケーションディレクトリにて以下を実行しておいてください。
これでspecファイルが保存される度にテストが自動で実行されます。
~ bundle exec guard
テストを書く
ここまでで準備は完了したので、いよいよ実際にテストを書いていきます。
GET /api/users/:id
はじめにこのURLのAPIが正常に動いているかどうかのテストを行います。
ちなみにこのAPIを定義しているcontrollerは以下のようになっています(簡易的に実装)。
# controller
def show
@user = User.find_by(id: params[:id])
render json: @user.response_format
end
# model
def response_format
user = {
username: self.username,
display_name: self.display_name
}
end
準備の時に作成した、users_spec.rbを開き、以下のように書いていきます。
require 'rails_helper'
RSpec.describe "Users", type: :request do
describe "GET /api/users/:id" do
before do
@user = FactoryGirl.create(:user, { username: "qita_test" })
get api_user_path(@user)
@json = JSON.parse(response.body)
end
it '200が返ってくる' do
expect(response).to be_success
expect(response.status).to eq 200
end
it '取得したデータのusernameがqita_test' do
expect(@json["username"]).to eq "qita_test"
end
end
end
これは、/api/users/:idに対してGETリクエストでアクセスした際に、
- 正常にhttp status codeが200を返す
- 取得したデータが指定したidのものである
ことを検証するためのテストとなります。
eqなどコード内で使われているマッチャに関しては、以下を参考に書くことが多いです。
POST /api/users
先ほどはGETのAPIのテストを書いたので、続いてPOSTのAPIのテストを書いていきます。
describe "POST /api/users" do
before do
@params = FactoryGirl.attributes_for(:user)
end
it '200が返ってくる' do
post api_users_path, @params
expect(response).to be_success
expect(response.status).to eq 200
end
it 'Userレコードが1増える' do
expect { post api_users_path, @params }.to change(User, :count).by(1)
end
end
これは、/api/usersに対してPOSTリクエストでアクセスした際に、
- 正常にhttp status codeが200を返す
- ちゃんとデータが保存され、増えている
ことを検証するためのテストとなります。
describe, context, itなどの単語で各文が始まっているかと思います。
どういう使い分け?と思った方は以下の記事を参考にしてみると良いかもしれません。