Edited at

RSpecを使ってAPIのテストを行う

More than 3 years have passed since last update.

最近やたらと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リクエストでアクセスした際に、

1. 正常にhttp status codeが200を返す

2. 取得したデータが指定した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リクエストでアクセスした際に、

1. 正常にhttp status codeが200を返す

2. ちゃんとデータが保存され、増えている

ことを検証するためのテストとなります。

describe, context, itなどの単語で各文が始まっているかと思います。

どういう使い分け?と思った方は以下の記事を参考にしてみると良いかもしれません。


参考