LoginSignup
26
33

More than 5 years have passed since last update.

Request SpecsでWebAPIのCRUDテスト例

Last updated at Posted at 2017-04-30

以前、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を編集

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

app/spec/factories/users.rb
FactoryGirl.define do
  factory :users_show, class: User do
    name "name_act1"
    mail "mail_act1@example.com"
  end
end

Rspec

app/spec/requests/users_spec.rb
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

app/spec/factories/users.rb
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

app/spec/requests/users_spec.rb
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

app/spec/factories/users.rb
FactoryGirl.define do
  factory :users_create, class: User do
    name "name_act3"
    mail "mail_act3@example.com"
  end
end

Rspec

app/spec/requests/users_spec.rb
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

app/spec/factories/users.rb
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

app/spec/requests/users_spec.rb
  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

app/spec/factories/users.rb
FactoryGirl.define do
  factory :users_delete, class: User do
    name "name_act5"
    mail "mail_act5@example.com"
  end
end

Rspec

app/spec/requests/users_spec.rb
  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
26
33
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
33