📭

ActionMailerをdeliver_nowなしでメール内容をテストする

2024/02/06に公開

ActionMailerのテストに関する記事をちらほら見かけますが、
そのほとんどがdeliver_nowを行い、
ActionMailer::Base.deliveriesを確認して…という流れのものがほとんどです。

文言が正しいかどうかだけ、送信先だけを検証するような単体テストであれば冗長なので、ActionMailer::Base.deliveriesを汚さないでMailerクラスの内容をテストする方法を、共有します。

やり方はシンプルで、deliver_nowを使用せずにMailerクラスを直接検証します。

require "rails_helper"

RSpec.describe UserMailer do
  let(:user) { create(:user) }
  describe "#notify_login" do
    let(:email) { UserMailer.notify_login(user) }
    it "subjectを検証する" do
      expect(email.subject).to eq "expected_subject"
    end
    it "本文を検証する" do
      expect(email.body.encoded.include?(user.name)).to eq true      
    end
    it "送信先を検証する" do
      expect(email.to).to eq([user.email])      
    end
  end
end

書いているコードはRSpecですがMinitestでも同じことができると思います。

deliver_nowをしないテストのメリット

ActionMailer::Base.deliveriesは便利ですが、
テストケースごとクリーンアップしないと、他にActionMailer::Base.deliveriesを使っているテストに悪影響を及ぼしがちでテストの管理コストは低くないです。弊社でもよくありました。
したがって、このようなTipsでメール送信自体を行わなくても送信内容を検証できることを頭の片隅に入れておくとよいと思いました。

OSIRO テックブログ

Discussion