My Day One

毎日東京の隅っこでコードを書いているエンジニアのブログです。

【Rails】gem deviseを使ってメール認証を実装した時に落ちるテストの対応

本記事の内容

deviseを使ってメール認証の機能を追加した際に、既存のテストが落ちてしまうという事象に遭遇しました。 今回の記事はそのテストが落ちないように修正した際に、どういった対応をしたのかをまとめたものになります。

状況

  • gem deivseを使ってログイン機能はすでに実装済
  • ログイン機能に関してのrpsecのコードも存在している(before { sign_in user } などのコード)
  • ログイン機能は実装していたが、ユーザーのアカウント登録時にメール認証の機能をつける必要があると判断したため、その機能を追加した
  • メール認証の機能を追加したところ、ログインが関係しているテストが全て落ちるようになった
  • Rubyのバージョンは3.1.2、Railsのバージョンは6.1.6

テストを走らせた時のエラー内容①

Failure/Error: = link_to t('devise.mailer.confirmation_instructions.action'), confirmation_url(@resource, confirmation_token: @token)
      
      ActionView::Template::Error:
        Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true

エラーの原因①

エラーメッセージに書いてある通りではあるんですが、リンク先となるhostがないため、hostパラメータを指定するか、default_url_options[:host]を設定するか、:only_pathをtrueに設定するなどする必要があるようです。

解決策①

エラーメッセージを検索してみるといくつかそれらしい記事が出てきました。 下記の記事にある通り、config/environments/test.rb にhostに関しての情報を追記することで、上記のエラーはなくなりました。

config.action_mailer.default_url_options = { host: "localhost", port: 3000 }

k-koh.hatenablog.com

これで、一件落着、めでたしめでたし...と思ったが、まだテストを走らせてもエラーが出ていたのでそちらも調査...。

テストを走らせた時のエラー内容②

Failure/Error: expect(response).to have_http_status(:ok)
       expected the response to have status code :ok (200) but it was :found (302)

エラーの原因②

ここのエラーが出ている箇所は、ログインした後のユーザーがあるページに遷移した際、そのページが正しく表示されているかをテストしているんですが、200ではなく302(リダイレクト )してしまっているようです。 リダイレクト するということは、そもそもテストデータ上ではログインがうまくいっていないためと思われます。

また、ログイン周りがうまくいかなくなっていることが原因で、データの作成や更新などのテストも複数落ちていました。

解決策②

こちらもたまたま、ほとんど答えが書いてある記事を見つけ、userをログインさせる前に、ユーザーを認証させるためのコードを書く必要がありました。

<変更前>

before { sign_in user } 

<変更後>

# 複数行になったのでbefore do ~ endを使う
before do
  user.confirm # ここを追加
  sign_in user
end

qiita.com

これで、テストも全て通るようになりました!

エラーメッセージをきちんと読んで検索する、ということで今回は解決に至りました👍