WebAPIをRSpecでテストする（更新API）

今回は更新APIのテストを実施したいと存じます。

#RSpecでテストするAPI
今日は4番の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/d065238ef9ee18cd8de3)

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

**テストするAPI**
PUT http://example.co.jp/update/id
すでにDBにデータが登録してあり、データをjson文字列で送付してDB更新、更新内容をjsonの形で返す

```rb:/home/ruby/app/controllers/user_controller.rb
  def update
    user  = User.find_by("id = ?",params[:num])
    if user.nil?
      render json: '{}' , status: 404
    else
      user.name = params[:name]
      user.mail = params[:mail]
      if user.save
        render json: user, status: :ok
      else
        render json: '{}', status: :ng
      end
    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でPUT送信される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 :Jupiter, class: User do
    name "Jupiter"
    mail "kusakari_kai@gmail.com"
  end
end
```

**テストコードに更新APIのテストを書く**

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

  describe 'PUT update' do
    before do
      @user = FactoryGirl.create(:Venus)
      put "update"
    end
    it "put update" do
      @params = FactoryGirl.attributes_for(:Jupiter)

      request_headers = {
        "HTTP_ACCEPT"  => "application/json",
        "CONTENT_TYPE" => "application/json",
        "DATA_TYPE"    => "json"
      }
      @params[:num] = @user.id.to_s
      expect {
        put "update", @params , request_headers
      }.to change { User.count }.by(0)
      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
```

**テスト実行**

```
Finished in 0.09974 seconds (files took 1.71 seconds to load)
5 examples, 0 failures, 1 pending
```

テスト実行前と、後でテーブルの件数が増えていないことを確認するようにしていますが、これだと適切なテストになっていませんね。その後レスポンスのステータスコードと、jsonの文字列内容によって、値が正しいか確認しています。以上！