Rails - テストで特定のメールを送信した ActionMailer をテストするにはどうすればよいですか
-
20-09-2019 - |
質問
現在、私のテストでは、電子メールが送信キューに入れられているかどうかをテストするために次のようなことを行っています
assert_difference('ActionMailer::Base.deliveries.size', 1) do
get :create_from_spreedly, {:user_id => @logged_in_user.id}
end
しかし、私がコントローラアクションで2つの異なる電子メールを送信できる場合、つまりサインアップが正常に完了した場合はユーザーに通知が送信され、何か問題が発生した場合は管理者に通知が送信されます。実際にどちらが送信されたかをテストするにはどうすればよいですか。上記のコードは関係なくパスします。
解決
テスト中に ActionMailer を使用すると、すべてのメールが という大きな配列に入れられます。 deliveries
. 。基本的に行っていること (そしてほとんどの場合はこれで十分です) は、電子メールが配列内に存在するかどうかを確認することです。ただし、特定の電子メールを具体的にチェックしたい場合は、実際に配列に何が格納されているかを知る必要があります。幸いなことに、電子メール自体は保存されているため、配列を反復処理して各電子メールを確認できます。
見る ActionMailer::Base 利用可能な構成方法を確認し、アレイ内にどの電子メールが存在するかを判断するために使用できます。あなたのケースに最も適した方法のいくつかはおそらく次のとおりです
recipients
:1 つ以上の電子メール アドレスを受け取ります。これらのアドレスに電子メールが配信されます。宛先を設定します:ヘッダ。subject
:メールの件名。件名を設定します。ヘッダ。
他のヒント
は、レール3のとおりactionmailerのは:: Base.deliveriesはメール::メッセージの配列です。 メールのドキュメントするます:
# mail['from'] = 'mikel@test.lindsaar.net'
# mail[:to] = 'you@test.lindsaar.net'
# mail.subject 'This is a test email'
# mail.body = 'This is a body'
#
# mail.to_s #=> "From: mikel@test.lindsaar.net\r\nTo: you@...
それから、統合
でメールのをテストするために簡単なはずmail = ActionMailer::Base.deliveries.last
assert_equal 'mikel@test.lindsaar.net', mail['from'].to_s
assert_equal 'you@test.lindsaar.net', mail['to'].to_s
現在のRSpecの構文を使用して、私は以下のものを使用して終了します:
last_email = ActionMailer::Base.deliveries.last
expect(last_email.to).to eq ['test@example.com']
expect(last_email.subject).to have_content 'Welcome'
私のテストのコンテキストは、私は歓迎メールは登録後、ユーザーに送信されたことを確認したかった機能仕様だっます。
テストフレームワーク shoulda のは、あなたがた電子メールについて、一定の条件を主張することができます優れたヘルパーを持っています送信されました。はい、あなたはActionMailer.deliveriesでそれを自分で行うことができますが、shouldaはそれをすべて1つの小ぎれいなブロック
作ります少し遅れて、それが他の人を助けることがあります:
あなたは、RSpecの/ Minitestのマッチャーとキュウリステップのコレクションをメールスペックを使用することができます。
ここで私はそれを行うことを見つけた最良の方法です。
1)このようなアクションメーラーコールバックのプラグインを含めます
script/plugin install git://github.com/AnthonyCaliendo/action_mailer_callbacks.git
私は本当にプラグインの主な機能を使用していないが、それは電子メールを送信するために使用された方法を把握することができるという素敵な機能を提供しています。
2)今、あなたはこのようなあなたのtest_helper.rbにいくつかのメソッドを置くことができます:
def assert_sent(method_name)
assert sent_num_times(method_name) > 0
end
def assert_not_sent(method_name)
assert sent_num_times(method_name) == 0
end
def assert_sent_once(method_name)
assert sent_num_times(method_name) == 1
end
def sent_num_times(method_name)
count = 0
@emails.each do |email|
count += 1 if method_name == email.instance_variable_get("@method_name")
end
count
end
3)今、あなたは、このような甘いテストを書くことができます
require 'test_helper'
class MailingTest < ActionController::IntegrationTest
def setup
@emails = ActionMailer::Base.deliveries
@emails.clear
end
test "should send a mailing" do
assert_difference "Mailing.count", 1 do
feeds(:feed1).generate_mailing
end
assert_sent_once "broadcast"
assert_not_sent "failed_mailing"
end
end
ここで「放送」と「mailing_failed」私のactionmailerの::基本クラスのメソッドの名前があります。これらは、あなたが通常のそれだMailer.deliver_broadcast(some_data)
またはMailer.deliver_failed_mailing(some_data)
などを呼び出すことによって、使用するものです!