WebAPIをRSpecでテストする（登録API）

前回、RSpecのインストールと設定を実施しました。その後GETリクエストのAPIテストを作成しましたが、今回は登録するAPIのテストを実施したいと存じます。

#RSpecでテストするAPI
前回に引き続き、今日は3番のAPIをテストします。

|NO|Method|URL|
|-----------:|:-----------|:------------|
|1|GET|http://example.com/select/|
|2|GET|http://example.com/select/id|
|3|POST|http://example.com/create/|
|4|PUT|http://example.com/update/id|
|5|DELETE|http://example.com/delete/id|

#本テスト関連の過去投稿
[**WebAPIをRSpecでテストする（準備+参照API）**](http://qiita.com/kaikusakari/items/450cde4940c3652659db)
[**WebAPIをRSpecでテストする（登録API）**]
(http://qiita.com/kaikusakari/items/43282c6882d7b8059df8)
[**WebAPIをRSpecでテストする（更新API）**](http://qiita.com/kaikusakari/items/b6e6fdebea5e6975bce0)
[**WebAPIをRSpecでテストする（削除API）**]
(http://qiita.com/kaikusakari/items/d065238ef9ee18cd8de3)

#テストコーディングと実施
今回テストするAPIは以下

**テストするAPI**
POST http://example.co.jp/create/
登録するユーザ情報をjson文字列で送付してDBに登録、登録内容をjsonの形で返す

```rb:/home/ruby/app/controllers/user_controller.rb
 def create
    user = User.new(user_params)
    if user.save
      result = User.where("id = ?",user.id);
      render json: result,status: :ok
    else
      render json: '{}',status: :ng
    end
 end
private
  def user_params
    params.permit(:name, :mail, :password, :password_confirmation)
  end
end
```

**テスト対象のAPIがデータ登録するテーブル構成**

```mysql
MariaDB [app]> desc users;
+-----------------+--------------+------+-----+---------+----------------+
| Field           | Type         | Null | Key | Default | Extra          |
+-----------------+--------------+------+-----+---------+----------------+
| id              | int(11)      | NO   | PRI | NULL    | auto_increment |
| name            | varchar(255) | YES  |     | NULL    |                |
| auth            | varchar(255) | YES  |     | NULL    |                |
| password_digest | varchar(255) | NO   |     | NULL    |                |
| mail            | varchar(255) | YES  |     | NULL    |                |
| created_at      | datetime     | NO   |     | NULL    |                |
| updated_at      | datetime     | NO   |     | NULL    |                |
+-----------------+--------------+------+-----+---------+----------------+
10 rows in set (0.00 sec)
```

#テストコードの修正
前回作成した参照APIのテストコードに、登録APIのテストコードを追加します


**ファクトリに登録APIでPOST送信されるjson文字列を追記**

```rb:/opt/app/spec/factories/user.rb
FactoryGirl.define do
  factory :Venus, class: User do
    name     "Venus"
    auth     "1234"
    password "kinsei"
    email    "kai.kuskari@gmail.com"
  end
  #追加ここから
  factory :Mercury, class: User do
    name "Mercury"
    mail "kai.kai.kai@gmail.com"
    password "suisei"
    password_confirmation "suisei"
  end
  #追加ここまで
end
```

**テストコードに登録APIのテストを追記**

```rb:/home/app/spec/controllers/user_controller_spec.rb
require 'rails_helper'

RSpec.describe UserController, type: :controller do
  describe 'GET select' do
    before do
      @user = FactoryGirl.create(:Venus)
      get "select"
    end
    it "get select" do
      expect(response).to be_success
      json = JSON.parse(response.body)
      expect(json[0]['name']).to eq @user.name
      expect(json[0]['auth']).to eq @user.auth
      expect(json[0]['mail']).to eq @user.mail
    end
  end
  #追加ここから
  describe 'POST create' do
    it "post create" do
      @params = FactoryGirl.attributes_for(:Mercury)

      request_headers = {
        "HTTP_ACCEPT"  => "application/json",
        "CONTENT_TYPE" => "application/json",
        "DATA_TYPE"    => "json"
      }
      expect {
        post "create", @params , request_headers
      }.to change { User.count }.by(1)
      expect(response).to be_success
      json = JSON.parse(response.body)
      expect(json[:name]).to eq @params['name']
      expect(json[:mail]).to eq @params['mail']
    end
  end
  #追加ここまで
end
```

テスト実行してもうまくいかず、試行錯誤した結果、問題なくテストが通りました。試行錯誤中は、テスト対象のAPI側に「logger hogehoge」を挿入して、変数の値を出力しつつ、少しづつテストを整備していました。これで登録APIの確認はできました。次回は更新API、削除APIを順次テスト整備していきたいと存じます。（いまさらですが、httpヘッダてAPI側でも参照していないため設定不要だったかも）