【RSpec】で書く「Rails Tutorial　７章」のテスト

<br>
こんにちは。

前回に引き続き↓
https://qiita.com/kakedashiit/items/7dac5bd2d3d522466d94
RSpecを使ってRailTutorial７章をクリアしました。

第７章は一応テストを書けはしましたが、
果たして正しい記述で正しいテストなのかが５０％ほどしか分かっていません。

だいぶ手探りでのテストを書いてしまったので
間違ってしまっている場合は遠慮せずにマサカリをお投げください。

***
###Rails Tutorial７章ですること

- 新規アカウント登録
- falshを用いたエラーメッセージ表示
- formページ作成・データ送信
- それぞれのテスト（RSpec）


***
###今回使用したSpecファイル

今回のテストで用いたSpec（テスト）ファイルは３つあります。
- ControllerのSpec
- RequestのSpec
- FeatureのSpec

>以前、System Specの登場により今後はFeature SpecではなくSystem Specを使う方が得策。とアドバイスをいただいたものの、すっかり忘れていてFeatureを書いてしまいました。。。

※それぞれのテストをどのSpecで行うべきか把握できておらず、本来あるべきSpecの場所ではない場所にテストが記述されている可能性があります。その際はご指摘ください。


####Spec（Controller）
```ruby:/spec/controllers/users_controller_spec.rb
require 'rails_helper'

RSpec.describe UsersController, type: :controller do

  describe "GET #new" do
    it "returns http success" do
      get :new
      expect(response).to have_http_status(:success)
    end
  end

  describe "error message check" do
  	it "return can't be blank" do
  		user = User.new()
  		user.valid?
  		expect(user.errors.messages[:name]).to include("can't be blank")
  	end
  end
end
```

####Spec（Request）
```ruby:/spec/requests/users_api_spec.rb
require 'rails_helper'

RSpec.describe "UsersApi", type: :request do

  let(:params){
     {name: "testuser1", email: "test@example.com", password: "test123", password_confirmation: "test123"}
  }

  before do
    get signup_path
  end


  describe "users#<create>" do
    it "postデータの受け取りができること" do
      post users_path, params: {user: params}

      expect(response).to have_http_status(302)
    end
  end
end
```

####Spec（Feature）
```ruby:/spec/features/users_spec.rb
require 'rails_helper'

RSpec.feature "Users", type: :feature do
  scenario "Signupページにページ遷移できるか" do
    visit root_path
    click_on "Sign up"

    expect(page).to have_content("Sign up")
  end

  scenario "ユーザー登録できること" do
  	user = FactoryBot.build(:user,name: "test",email: "test@example.org", password: "abcdefg", password_confirmation: "abcdefg")
  	visit new_user_path

  	expect {
    fill_in "Name", with: user.name
    fill_in "Email", with: user.email
    fill_in "Password", with: user.password
    fill_in "Confirmation", with: user.password_confirmation
  	click_button "Create my account"
    }.to change(User, :count).to(1)
  end

  scenario "エラーメッセージが正しく表示されること" do
  	visit new_user_path

    fill_in "Name", with: " "
    fill_in "Email", with: " "
    fill_in "Password", with: " "
    fill_in "Confirmation", with: " "
    click_button "Create my account"

    expect(page).to have_content("can't be blank")

  end
end
```

***

###まとめ・反省点
前回に引き続き、「RSpec」の理解が十分ではないと実感しました。
まず、何をテストするべきなのかを理解しておらず、
いざ実装しようにもどのSpecに記述すればいいのかが分かりませんでした。

また、それぞれのSpecでの記述の違いにより思わぬエラー無双に陥りました。

力不足だと実感しました。
まだまだ覚えることはたくさんありますので
アドバイス・ご指摘等いただけますとありがたいです。
<br>
***
**変更履歴**
10/27
@eRy-sk さんより下のような解説アドバイスをいただきました。
[Request Specのアドバイス](https://scrapbox.io/buta-memo/%E3%81%94%E3%81%84%E3%81%95%E3%82%93)

その内容を現在のRequest Specに反映しています。
@eRy-sk さんありがとうございました。

ただ、最初のletにparamsを格納しておいて活用する記述だとエラーが出たため、
下のように変更させていただきました。

```ruby:/spec/requests/users_api_spec.rb
let(:params) {
     {
       user: {
         name: "TestUser1",
         email: "test@example.com",
         password: "test123",
         password_confirmation: "test123"
       }
     }
   }

#他記述

it "postデータの受け取りができること" do
  post users_path, params
  #他記述
end
```

```ruby:/spec/requests/users_api_spec.rb
let(:params){
  { name: "TestUser1",
    email: "test@example.com",
    password: "test123", 
    password_confirmation: "test123"
   }
}

#他記述

it "postデータの受け取りができること" do
  post users_path, params: {user: params}
  #他記述
end
```

こんな感じにするときちんとエラーなくテストできます。
![スクリーンショット 2018-10-27 16.10.44.png](https://qiita-image-store.s3.amazonaws.com/0/260354/81ffdc0d-bfee-d2fe-f870-0c9e3e10dd8e.png)

他アドバイスやマサカリも随時受け付けているので
みなさん引き続きよろしくお願いします。
<br>