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の抹茶を作ってみました。
READMEそのまんまですが、こんな感じでexpect
にblockを渡します。
it 'メールが送られる' do
expect {
# 〜なんか素敵な処理〜
}.to deliver to: 'to@example.org', subject: 'Hello world'
end
subject
とis_expected
を使うと更にシンプルに。
subject {
proc { # 〜なんか素敵な処理〜 }
}
it { is_expected.to deliver to: 'to@example.org', subject: 'Hello world' }
比較対象としてto
とsubject
、from
が使えます。完全一致するメールがある場合のみTrueとなります。
it { is_expected.to deliver to: 'to@example.org', subject: 'Hello world', from: 'from@example.org' }
gemを作って紹介記事まで書くのは初めてなので、アドバイスやご指摘など頂けるととっても嬉しいです。
以上、2019年の書き初めでした。