現在、私のテストでは、電子メールが送信されるためにキューに入れられているかどうかをテストするためにこのようなことをしています
assert_difference('ActionMailer::Base.deliveries.size', 1) do
get :create_from_spreedly, {:user_id => @logged_in_user.id}
end
しかし、コントローラーアクションが2つの異なる電子メールを送信できる場合、つまり、サインアップがうまくいくとユーザーに1つ、何かがうまくいかなかった場合は管理者に通知する-実際に送信されたものをテストするにはどうすればよいですか?上記のコードは関係なく渡されます。
テスト中にActionMailerを使用する場合、すべてのメールはdeliveries
という大きな配列に入れられます。基本的に何をしているのか(ほとんどの場合は十分です)は、配列内に電子メールが存在するかどうかを確認することです。しかし、特定の電子メールを特に確認したい場合は、実際に配列に保存されているものを知る必要があります。幸いなことに、電子メール自体が保存されているため、配列を反復処理して各電子メールを確認できます。
ActionMailer :: Base を参照して、使用可能な構成メソッドを確認してください。この構成メソッドを使用して、配列に存在する電子メールを判別できます。あなたのケースに最も適した方法のいくつかはおそらく
recipients
:1つ以上のメールアドレスを取得します。これらのアドレスは、メールの配信先です。 To:ヘッダーを設定します。subject
:メールの件名。 Subject:ヘッダーを設定します。Rails 3 ActionMailer :: Base.deliveriesはMail :: Messageの配列です。 メールドキュメンテーション から:
# mail['from'] = '[email protected]'
# mail[:to] = '[email protected]'
# mail.subject 'This is a test email'
# mail.body = 'This is a body'
#
# mail.to_s #=> "From: [email protected]\r\nTo: you@...
それからあなたのメールの統合を簡単にテストできるはずです
mail = ActionMailer::Base.deliveries.last
assert_equal '[email protected]', mail['from'].to_s
assert_equal '[email protected]', mail['to'].to_s
現在のRspec構文を使用して、次を使用することになりました。
last_email = ActionMailer::Base.deliveries.last
expect(last_email.to).to eq ['[email protected]']
expect(last_email.subject).to have_content 'Welcome'
テストのコンテキストは、サインアップ後にウェルカムメールがユーザーに送信されることを確認したい機能仕様でした。
テストフレームワーク shoulda には、送信された電子メールに関する特定の条件をアサートできる優れたヘルパーがあります。はい、ActionMailer.deliveriesを使用して自分で実行できますが、shouldaはすべてを1つの小さなブロックにまとめます
少し遅れましたが、他の人に役立つかもしれません:
Email-spec 、Rspec/MinitestマッチャーとCucumberステップのコレクションを使用できます。
これが、私が見つけた最善の方法です。
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
_
ここで、「broadcast」と「mailing_failed」は、ActionMailer :: Baseクラスのメソッドの名前です。これらは、通常Mailer.deliver_broadcast(some_data)
またはMailer.deliver_failed_mailing(some_data)
などを呼び出すことで使用するものです。それだけです!