Rails
RSpec
ActionMailer

RSpecでActionMailerのテストをシンプルに書けるgem作った

featureテストなどで、メール送信を含む一連のアクションをテストしたい時、毎回こういうことやってました。

before do

ActionMailer::Base.deliveries.clear
end

it do
# 〜なんかテキトーな処理〜

expect(ActionMailer::Base.deliveries.first).to be_present
expect(ActionMailer::Base.deliveries.first.to).to include 'to@example.org'
end

あるアクションで送信されるメールが一通ならfirstで大丈夫ですが、ユーザーと管理者にそれぞれ送っている場合、送る順番が変わるとfirstで取れないのでfindとかで配列操作したりして、結構面倒でした。

また、ActionMailer::Base.deliveries.clearを忘れると別のテストで送ったメールが残っていたりして、「なぜか関係ないメールが送られてる???」となることもありました。

そこで、とりあえず何か処理したらそれによって意図したメールが送られているか、それだけのテストをシンプルに書けるように、RSpecの抹茶を作ってみました。

https://github.com/d-mato/rspec-mailer_matcher

READMEそのまんまですが、こんな感じでexpectにblockを渡します。

it 'メールが送られる' do

expect {
# 〜なんか素敵な処理〜
}.to deliver to: 'to@example.org', subject: 'Hello world'
end

subjectis_expectedを使うと更にシンプルに。

subject {

proc { # 〜なんか素敵な処理〜 }
}

it { is_expected.to deliver to: 'to@example.org', subject: 'Hello world' }

比較対象としてtosubjectfromが使えます。完全一致するメールがある場合のみTrueとなります。

it { is_expected.to deliver to: 'to@example.org', subject: 'Hello world', from: 'from@example.org' }

gemを作って紹介記事まで書くのは初めてなので、アドバイスやご指摘など頂けるととっても嬉しいです。

以上、2019年の書き初めでした。