Loading

BLOG

RailsのActionMailerをテストするには

 

つい先日マンションマーケットのメールの改訂作業をしました。
以前はERB形式だったメールをSlim形式にし、タイトルや文面を変更しました。
その時にいろいろ調べたActionMailer関連の使えるノウハウをご紹介します。

メールがきちんと送られてるか見る

あるアクション―例えば会員登録―の後にメールが送信されるとします。
そんなときは、ローカルで、サーバーを立ち上げて会員登録するとログウィンドウにメールの文面がBase64形式で出てくるはずです。
これをデコードしてあげれば文面が見れます。
ちょっとめんどくさいですね・・・・・。

そんな時にはこのGemです。
Letter Opener
メールが送信されるアクションを起こすと、Gemが自動的にメールをブラウザの新しいウィンドウで開いてくれます。

メールの文面が正しいかどうかテストする

メールのタイトルや文面を動的に生成しているとします。
たとえば「(ユーザー名)様にメッセージが届いています」といったようなタイトルや
「(ユーザー名)様 こんにちは!」と言ったような文面です。

きっちり動的に生成されてるかテストするにはどうしたらいいのでしょう。
Rspecだとこんな感じでテストできます。

RSpec.describe ConsumerMailer, type: :mailer do

  let (:user) {create (:user, name: '試験太郎')}

  describe '#got_a_message' do
    it '顧客にメッセージが届いた時のメール' do
      mail = ConsumerMailer.got_a_message(user)

      expect(mail.subject).to eq('試験太郎様にメッセージが届いています')
      expect(mail.body.raw_source).to match(/試験太郎様こんにちは!/)
    end
  end
end

メーラーオブジェクトに対してsubject,body.raw_sourceなどと指定してあげるとテキストが取れます。

アクションを起こさずにメールの出力が見たい

メールのViewを修正して、会員登録などのアクションをローカルで起こして、先ほどのLetter Opnerで開いて、もう一回直して・・・・・
とやるのはとても面倒です。 メーラーだけ開けないのでしょうか?

ActionMailerにはPreview機能がデフォルトでついています。これを使うととても楽に出来ます。

このPreviewはメーラーを生成するときに同時に作られます。Rspecを使っているのであれば、
spec/mailers/preview/ 以下を見てください

生成されるファイルの一覧はこちら

まずルーターの設定を変更しましょう

get '/rails/mailers' => "rails/mailers#index"
get '/rails/mailers/*path' => "rails/mailers#preview"

をルーターに追加してください。(ルーターの一番上の行がよいでしょう。私は下の方に追加してしばらくハマりました。)

続いて spec/mailers/preview/ 以下のファイルを(例としてさっきのgot_a_messageを使っています。)

class ConsumerMailerPreview < ActionMailer::Preview def got_a_message user = User.first # => Developmentにすでにあるデータを使っています。
      ConsumerMailer.got_a_message(user)
  end
end

のようにします。この後、先ほど作った /rails/mailers にアクセスしましょう。
そうすると、メソッド名と同名のリンク先だけのシンプルなページが表示されます。一つ一つのリンクがメールのプレビューです。

ここで注意しなくてはいけないのはデータの扱いです。先ほどのテストと違ってこのプレビューはDevelopment環境にアクセスしているようです。FactoryGirlを使ってデータを作ってしまうと、DevelopmentにデータができてDBを汚してしまいます(私も実際やりました)。
ですから、Development環境にシードなどですでに挿入されているデータを使うとよいでしょう。

おまけ メールが絡む一連のアクションをテストしたいとき

たとえば会員登録をした後にメールが送られるとします。
会員登録がきちんとできて、送られるメールの内容も正しいこともテストするにはどうしたらいいでしょう。

config/environment/test.rb を開いて

config.action_mailer.delivery_method = :test

としてあげればいいだけです。 こうすると送信されたメールが ActionMailer::Base.deliveries という配列にたまるようになります。

こんな感じでテストできます。

    context '会員登録するとメールが送られる' do
      before do
        # RailsがメールをためておくArrayをテスト前にクリアします。
        ActionMailer::Base.deliveries.clear
        @mail_array = ActionMailer::Base.deliveries
      end

      # RailsがメールをためておくArrayをテスト後にクリアします。
      after { ActionMailer::Base.deliveries.clear }

      it '会員登録するとメールが送られる' do
            ###ログイン処理のテスト###

        expect(@mail_array.count).to eq(1)
      end

      it 'メールに挨拶文がある' do
        expect(@mail_array.first.body.raw_source).to match(/試験太郎様こんにちは!/)
      end
    end
  end

参考

難しく考えずにやりきることが大切

「日刊工業新聞」に掲載されました

関連記事

  1. サイトデザイン史

    2016.06.30
  2. 良いお年を

    2014.12.26
  3. 買い物上手とは?

    2015.04.24
  4. 購入サポートのコンサルタントの仕事内容とは?

    2016.07.04
  5. 狂騒の時代

    2015.06.05
  6. 知識や経験だけで売るものではない

    2016.05.27
PAGE TOP