Rails6でRSpecのコントローラテストをしようとするとエラーが発生する

## はじめに

[Everyday Rails - RSpecによるRailsテスト入門](https://leanpub.com/everydayrailsrspec-jp)を見ながら、
勉強がてらアプリにRSpecを追加していましたが、
Rails6特有のエラーが発生しましたのでご紹介します。

### 2019/12/18追記

[Everyday Rails - RSpecによるRailsテスト入門](https://leanpub.com/everydayrailsrspec-jp) の翻訳者の一人である、
@jnchito さんがRails6でRSpecを使用する際の変更点を挙げられた記事があります。

Rails6でRSpecを使用する際の変更点が網羅されていますので、
ぜひご参照ください。

[【動画付き】Everyday RailsのサンプルアプリをRails 6で動かす際に必要なテストコードの変更点 - give IT a try](https://blog.jnito.com/entry/2019/10/25/053521)

## 開発環境のバージョン

```console
$ ruby -v
ruby 2.6.4p104 (2019-08-28 revision 67798) [x86_64-darwin18]
$ rails -v
Rails 6.0.2
```

`rspec-rails 3.9.0` を使用していました。

## 発生したエラー

下記のようなコントローラのスペックファイルを書いて実行すると、
警告とエラーが発生しました。

```ruby:spec/controllers/static_pages_controller_spec.rb
  describe '#home' do
    it "正常なレスポンスを返す" do
      get :home
      expect(response).to be_success
    end
  end
```

```console
$ rspec spec/controllers/static_pages_controller_spec.rb 

StaticPagesController
  #home
DEPRECATION WARNING: formats is deprecated and will be removed from Rails 6.1 (called from block (3 levels) in <top (required)> at /Users/amatsuki/programing/portfolio/study_roadmap/spec/controllers/static_pages_controller_spec.rb:6)
DEPRECATION WARNING: ActionView::Template#initialize requires a locals parameter (called from block (3 levels) in <top (required)> at /Users/amatsuki/programing/portfolio/study_roadmap/spec/controllers/static_pages_controller_spec.rb:6)
DEPRECATION WARNING: formats is deprecated and will be removed from Rails 6.1 (called from block (3 levels) in <top (required)> at /Users/amatsuki/programing/portfolio/study_roadmap/spec/controllers/static_pages_controller_spec.rb:6)
DEPRECATION WARNING: ActionView::Template#initialize requires a locals parameter (called from block (3 levels) in <top (required)> at /Users/amatsuki/programing/portfolio/study_roadmap/spec/controllers/static_pages_controller_spec.rb:6)
DEPRECATION WARNING: formats is deprecated and will be removed from Rails 6.1 (called from block (3 levels) in <top (required)> at /Users/amatsuki/programing/portfolio/study_roadmap/spec/controllers/static_pages_controller_spec.rb:6)
DEPRECATION WARNING: ActionView::Template#initialize requires a locals parameter (called from block (3 levels) in <top (required)> at /Users/amatsuki/programing/portfolio/study_roadmap/spec/controllers/static_pages_controller_spec.rb:6)
    正常なレスポンスを返す (FAILED - 1)

Failures:

  1) StaticPagesController#home 正常なレスポンスを返す
     Failure/Error: get :home
     
     ActionView::Template::Error:
       wrong number of arguments (given 2, expected 1)
     # ./spec/controllers/static_pages_controller_spec.rb:6:in `block (3 levels) in <top (required)>'
     # ------------------
     # --- Caused by: ---
     # ArgumentError:
     #   wrong number of arguments (given 2, expected 1)
     #   ./spec/controllers/static_pages_controller_spec.rb:6:in `block (3 levels) in <top (required)>'
```

## 原因

Rails6でのRSpecのバグのようです。
Issuesにもいくつか挙げられていました。

[github/rails - Warning formats is deprecated and will be removed from Rails 6.1](https://github.com/rspec/rspec-rails/issues/2094)

[github/rspec-rails - Warning formats is deprecated and will be removed from Rails 6.1](https://github.com/rails/rails/issues/35417)

[github/rspec-rails - Changes In Rails 6 ActionView::Template Breaks EmptyTemplateHandler](https://github.com/rspec/rspec-rails/issues/2086)

## rails-rspecのバージョンを4.0.0.beta3にする

先ほどのリンクで指摘されていたように、
rails-rspecのバージョンを`4.0.0.beta2`にあげます。

まずはコマンドでインストールできるバージョンの中に`4.0.0.beta2`があるか、
他に最新のバージョンはあるか確認します。
下記の`gem query`はローカルまたはリモートリポジトリのgemの情報を取得するものです。

```console
$ gem query -rae --prerelease 'rspec-rails'
```

今回使用したオプションの意味は下記のようになっています。

|オプション|意味|
|--:|--:|
|-r|リモートに指定|
|-a|全てのgemのバージョンを表示|
|-e|完全一致したgemを指定|
|--prerelease|プレリリースバージョンも表示|

gemコマンドの詳細はrubygems.orgのページを参照してください。
[rubygems - Guides](https://guides.rubygems.org/command-reference/#gem-query)

### gem queryコマンド実行

コマンドを実行してみると、
`4.0.0.beta2`があることを確認できました。

さらに、`4.0.0.beta3`があることも確認できました。（2019/12/18現在）
バージョンは高い方がよしとされていますので、今回は`4.0.0.beta3`の方をインストールします。

```console
$ gem query -rae --prerelease 'rspec-rails'

*** REMOTE GEMS ***

rspec-rails (4.0.0.beta3, 4.0.0.beta2, 3.9.0, 3.8.3, 3.8.2, 3.8.1, 3.8.0, 3.7.2, 3.7.1, 3.7.0, 3.6.1, 3.6.0, 3.6.0.beta2, 3.6.0.beta1, 3.5.2, 3.5.1, 3.5.0, 3.5.0.beta4, 3.5.0.beta3, 3.5.0.beta2, 3.5.0.beta1, 3.4.2, 3.4.1, 3.4.0, 3.3.3, 3.3.2, 3.3.1, 3.3.0, 3.2.3, 3.2.2, 3.2.1, 3.2.0, 3.1.0, 3.0.2, 3.0.1, 3.0.0, 3.0.0.rc1, 3.0.0.beta2, 3.0.0.beta1, 2.99.0, 2.99.0.rc1, 2.99.0.beta2, 2.99.0.beta1, 2.14.2, 2.14.1, 2.14.0, 2.14.0.rc1, 2.13.2, 2.13.1, 2.13.0, 2.12.2, 2.12.1, 2.12.0, 2.11.4, 2.11.0, 2.10.1, 2.10.0, 2.9.0, 2.9.0.rc2, 2.8.1, 2.8.0, 2.8.0.rc2, 2.8.0.rc1, 2.7.0, 2.7.0.rc1, 2.6.1, 2.6.1.beta1, 2.6.0, 2.6.0.rc6, 2.6.0.rc4, 2.6.0.rc2, 2.5.0, 2.4.1, 2.4.0, 2.3.1, 2.3.0, 2.2.1, 2.2.0, 2.1.0, 2.0.1, 2.0.0, 2.0.0.rc, 2.0.0.beta.22, 2.0.0.beta.20, 2.0.0.beta.19, 2.0.0.beta.18, 2.0.0.beta.17, 2.0.0.beta.16, 2.0.0.beta.15, 2.0.0.beta.14.2, 2.0.0.beta.14.1, 2.0.0.beta.13, 2.0.0.beta.12, 2.0.0.beta.11, 2.0.0.beta.10, 2.0.0.beta.9.1, 2.0.0.beta.8, 2.0.0.beta.7, 2.0.0.beta.6, 2.0.0.beta.5, 2.0.0.beta.4, 2.0.0.beta.3, 2.0.0.beta.2, 2.0.0.beta.1, 2.0.0.a10, 2.0.0.a9, 2.0.0.a8, 2.0.0.a7, 2.0.0.a6, 2.0.0.a5, 2.0.0.a4, 2.0.0.a3, 2.0.0.a2, 1.3.4, 1.3.3, 1.3.3.rc, 1.3.2, 1.3.1, 1.3.0, 1.2.9, 1.2.7.1, 1.2.7, 1.2.6, 1.2.5, 1.2.4, 1.2.3, 1.2.2, 1.2.1, 1.2.0, 1.1.12, 1.1.11, 1.1.10, 1.1.9, 1.1.8, 1.1.7, 1.1.6, 1.1.5)
```

### bundleでインストール

bundleを使用しているので`Gemfile`を下記のように修正します。

```ruby:Gemfile
  gem 'rspec-rails', '4.0.0.beta3'
```

そして、インストールします。

```console
$ bundle
```

### 再度テストを実行

めでたしめでたし、、、と思いきやまたもやエラーが発生。。。

```console
$ rspec spec/controllers/static_pages_controller_spec.rb 

StaticPagesController
  #home
    正常なレスポンスを返す (FAILED - 1)

Failures:

  1) StaticPagesController#home 正常なレスポンスを返す
     Failure/Error: expect(response).to be_success
       expected #<ActionDispatch::TestResponse:0x00007ff5c5326f78 @mon_mutex=#<Thread::Mutex:0x00007ff5c5326be0>, @mo...ders:0x00007ff5c536d4f0 @req=#<ActionController::TestRequest:0x00007ff5c5327310 ...>>, @variant=[]>> to respond to `success?`
     # ./spec/controllers/static_pages_controller_spec.rb:7:in `block (3 levels) in <top (required)>'

Finished in 0.11472 seconds (files took 5.48 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/controllers/static_pages_controller_spec.rb:5 # StaticPagesController#home 正常なレスポンスを返す
```

## Rails6でbe_successメソッドは使えない

Rails6からは`be_success`メソッドは使用できなくなっているようです。。
`be_success`を`be_successful`に置き換えるようにしている記事がいくつかありました。

[Rails 5.2 betaを使ったRSpec 実行時に be_success へされる非推奨警告](http://koic.hatenablog.com/entry/deprecation-warning-success-predicate-is-deprecated-and-will-be-removed-in-rails6)

[Gist - Replace 'be_success' to 'be_successful'.md](https://gist.github.com/taketo1113/f4ab9b5eb750d223b28245f0c91f5a19)

```diff:spec/controllers/static_pages_controller_spec.rb
  describe '#home' do
    it "正常なレスポンスを返す" do
      get :home
-       expect(response).to be_success
+       expect(response).to be_successful
    end
  end
```

### 再々度テストを実行

やっと通りました。。。

```console
$ rspec spec/controllers/static_pages_controller_spec.rb 

StaticPagesController
  #home
    正常なレスポンスを返す

Finished in 0.04691 seconds (files took 2.47 seconds to load)
1 example, 0 failures
```

めでたしめでたし。

## 最後に

これからはコントローラのテストはなくなって、
統合テスト等に置き換わっていくんですよね。

コード量が少なくなるのはいいことですね。