【RSpec】Railsチュートリアル第6版　第3章

#はじめに
Railsチュートリアル第6版ではテストフレームワークとして**Minitest**が採用されているが、実際に現場で使われることの多い**RSpec**を用いて、第3章から第14章において作成するsample_appのテストを書いていく。
テストする内容自体は基本的にはチュートリアルの内容に沿って進めていく。
また、RSpecの書き方については、[『Everyday Rails - RSpecによるRailsテスト入門』](https://leanpub.com/everydayrailsrspec-jp)という書籍を参考にしている。

###目次
- 第3章（本記事）
- [第4章](https://qiita.com/supyolo888/items/939b670b62eb18467f6d)
- [第5章](https://qiita.com/supyolo888/items/42234ac2ed3919b14586)
- [第6章](https://qiita.com/supyolo888/items/bd10e64c77fe391cf203)
- [第7章](https://qiita.com/supyolo888/items/d2824ced26402b5f58d1)
- [第8章](https://qiita.com/supyolo888/items/508caaa40edf307093ed)
- [第9章](https://qiita.com/supyolo888/items/62e471b07a0c9a81575d)
- [第10章](https://qiita.com/supyolo888/items/a8695b20ec8082f85223)
- [第11章](https://qiita.com/supyolo888/items/5c81331e46f1d9d5ab3c)
- [第12章](https://qiita.com/supyolo888/items/fbb95671d39dfbf9df90)
- [第13章](https://qiita.com/supyolo888/items/c88b6acd4ff55750defc)
- [第14章](https://qiita.com/supyolo888/items/532390902bf3e0f5348e)

#事前準備
Gemfileにrspecを追加

```rb:Gemfile
group :development, :test do
  gem 'rspec-rails'
end
```

RSpecをインストール

```
$ rails generate rspec:install
```

ジェネレーターの設定を変更

```config/application.rb
module App
  class Application < Rails::Application
    config.load_defaults 6.1
    config.generators do |g|
      g.test_framework :rspec,
      view_specs: false,
      helper_specs: false,
      routing_specs: false
    end
  end
end
```

#Minitest

####StaticPagesコントローラーのテスト

```rb:test/controllers/static_pages_controller_test.rb
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  def setup
    @base_title = "Ruby on Rails Tutorial Sample App"
  end

  test "should get home" do
    get static_pages_home_url
    assert_response :success
    assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
    assert_select "title", "Help | Ruby on Rails Tutorial Sample App"
  end

  test "should get about" do
    get static_pages_about_url
    assert_response :success
    assert_select "title", "About | Ruby on Rails Tutorial Sample App"
  end

end
```

#RSpec

####StaticPagesコントローラーのテスト

```rb:spec/requests/static_pages.rb
require 'rails_helper'

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

  let(:base_title) { "Ruby on Rails Tutorial Sample App" }

  describe "GET /home" do
    it "returns http success" do
      get "/home"
      expect(response).to have_http_status(:success)
      assert_select "title", "Home | #{base_title}"
    end
  end

  describe "GET /help" do
    it "returns http success" do
      get "/help"
      expect(response).to have_http_status(:success)
      assert_select "title", "Help | #{base_title}"
    end
  end

  describe "GET /about" do
    it "returns http success" do
      get "/about"
      expect(response).to have_http_status(:success)
      assert_select "title", "About | #{base_title}"
    end
  end

end
```
StaticPagesコントローラーを作成するとrequest specが自動で作成されている。
Rails5以降、コントローラー機能のテストはrequest specによる記述が推奨されているらしいのでそちらを使用。
また、`@base_title`を定義していた`def setup`は`let`による遅延読み込みで代用。

#発生するエラーについて

第8章においても記述しているが、不明なエラーが発生した場合はこちらを参考にしていただきたい。

*spec/rails_helper.rb*内の

```rb:spec/rails.helper.rb
ENV['RAILS_ENV'] ||= 'test'
```

を

```rb:spec/rails.helper.rb
ENV['RAILS_ENV'] = 'test'
```

に変更する。

RSpecを作成した際、`ENV['RAILS_ENV'] ||= 'test'`が自動で記述され、RSpecのデフォルトの環境変数にはtestが適用されるはずが、なぜかRails.env="development"になっており、エラーが発生していた。
これにより、RSpecのデータベースに開発環境用のデータベースが使用されており、また通常テスト環境には適用されないCSRFチェックが働き、422エラーなどを発生させていた。
かなりハマってしまったので是非参考にしていただきたい。