以前、Rspecの記事を書きましたがController Specsを利用していました。今回はRequest Specsを利用します。この記事では、RailsをAPIモードで作成した後の状態からRspecを導入して、参照・登録・更新・削除するAPIのテストコードを書くところまで行きます。
テストコードは冗長な部分がありますが、できるだけテストの流れが分かりやすく見えるようなメソッドを選んでいます。
テスト実施したソースコードは以下をご覧ください。
GitHub - rspec_api
本記事は、以下の公式の導入手順に沿って進めています。
GitHub - rspec/rspec-rails: RSpec for Rails-3+
対象バージョン
ruby
2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]
Gem
名前 | バージョン |
---|---|
Rails | 5.0.2 |
Rspec | 3.5.4 |
rspec-rails | 3.5.2 |
factory_girl_rails | 4.8.0 |
環境の構築
テストを実施する上で必要な環境を整えます。
まずはプロジェクトと、テスト対象のコントローラ・DBを作成します。
$ rails new app --api
$ rails generate scaffold User name:string mail:string
$ rake db:migrate
$ rake db:migrate RAILS_ENV=test
$ ls -l app/db/
test.sqlite3
必要なGemfileを編集
~略~
group :development, :test do
gem 'rspec-rails'
gem 'factory_girl_rails'
end
インストール実施
$ bundle install
$ rails generate rspec:install
create .rspec
create spec
create spec/spec_helper.rb
create spec/rails_helper.rb
$ bundle exec rspec
No examples found.
Finished in 0.00065 seconds (files took 0.20726 seconds to load)
0 examples, 0 failures
環境を準備したので、APIのテストコードを作成します。
(今回はGemの通り、factory_girlを利用します)
テスト対象API
対象APIは以下の通り
NO | method | path | proxy |
---|---|---|---|
1 | GET | /users/:id(.:format) | users#show |
2 | GET | /users(.:format) | users#index |
3 | POST | /users(.:format) | users#create |
4 | PUT | /users/:id(.:format) | users#update |
5 | DELETE | /users/:id(.:format) | users#destroy |
1 GET /users/:id(.:format)
一つのレコードを参照するAPIを確認します。
FG
FactoryGirl.define do
factory :users_show, class: User do
name "name_act1"
mail "mail_act1@example.com"
end
end
Rspec
require 'rails_helper'
RSpec.describe "Users", type: :request do
describe "GET /users/:id" do
before do
@user = FactoryGirl.create(:users_show)
end
it "res code 200" do
get "/users" + "/" + @user[:id].to_s
expect(response.status).to eq 200
json = JSON.parse(response.body)
expect(@user.name).to eq json['name']
end
end
end
2 GET /users/(.:format)
テーブルの全レコードを参照するAPIを確認します。
FG
FactoryGirl.define do
factory :users_index_1, class: User do
name "name_act2"
mail "mail_act2@example.com"
end
factory :users_index_2, class: User do
name "name_act2"
mail "mail_act2@example.com"
end
end
Rspec
require 'rails_helper'
RSpec.describe "Users", type: :request do
describe "GET /users" do
before do
FactoryGirl.create(:users_index_1)
FactoryGirl.create(:users_index_2)
end
it "res code 200" do
get "/users"
expect(response.status).to eq 200
json = JSON.parse(response.body)
expect(User.count).to eq json.count
end
end
end
3 POST /users(.:format)
1レコードを登録するAPIを確認します。
FG
FactoryGirl.define do
factory :users_create, class: User do
name "name_act3"
mail "mail_act3@example.com"
end
end
Rspec
require 'rails_helper'
describe "POST /users" do
before do
@user = FactoryGirl.attributes_for(:users_create)
end
it "res code 200" do
post "/users", :user => @user, :name => @user[:name], :mail => @user[:mail]
expect(response.status).to eq 201
json = JSON.parse(response.body)
expect(@user[:name]).to eq json['name']
end
end
RSpec.describe "Users", type: :request do
end
4 PUT /users/:id(.:format)
1レコードを更新するAPIを確認します。
FG
FactoryGirl.define do
factory :users_update_before, class: User do
name "name_act4"
mail "mail_act4@example.com"
end
factory :users_update_after, class: User do
name "name_act4_after"
mail "mail_act4_after@example.com"
end
end
Rspec
describe "PUT /users/:id" do
before do
@user_before = FactoryGirl.create(:users_update_before)
@user = FactoryGirl.attributes_for(:users_update_after)
end
it "res code 200" do
put "/users" + "/" + @user_before.id.to_s, :user => @user, :name => @user[:name], :mail => @user[:mail]
expect(response.status).to eq 200
json = JSON.parse(response.body)
expect(@user[:name]).to eq json['name']
end
end
5 DELETE /users/:id(.:format)
1レコードを削除するAPIを確認します。
FG
FactoryGirl.define do
factory :users_delete, class: User do
name "name_act5"
mail "mail_act5@example.com"
end
end
Rspec
describe "DELETE /users/:id" do
before do
@user = FactoryGirl.create(:users_delete)
end
it "res code 204" do
expect {
delete "/users" + "/" + @user.id.to_s
}.to change{ User.count }.by(-1)
expect(response.status).to eq 204
end
end
end