51

現在、私のテストでは、電子メールが送信されるためにキューに入れられているかどうかをテストするために、このようなことをしています

assert_difference('ActionMailer::Base.deliveries.size', 1) do       
  get :create_from_spreedly, {:user_id => @logged_in_user.id}
end

しかし、コントローラーアクションが2つの異なるメールを送信できる場合、つまり、サインアップが成功した場合はユーザーに1つ、何か問題が発生した場合は管理者に通知を送信できる場合、どちらが実際に送信されたかをテストするにはどうすればよいですか. 上記のコードは関係なく合格します。

4

7 に答える 7

82

Rails 3 以降、ActionMailer::Base.deliveries は Mail::Message の配列です。メールのドキュメントから:

#  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
于 2010-08-18T23:56:11.757 に答える
31

テスト中に ActionMailer を使用すると、すべてのメールが という大きな配列に入れられdeliveriesます。あなたが基本的に行っていること (そしてほとんどは十分です) は、電子メールが配列に存在するかどうかを確認することです。しかし、特定の電子メールを特定してチェックしたい場合は、配列に実際に何が格納されているかを知る必要があります。幸いなことに、電子メール自体は保存されているため、配列を反復処理して各電子メールをチェックできます。

ActionMailer::Baseを参照して、配列に存在する電子メールを特定するために使用できる構成メソッドを確認してください。あなたのケースに最も適した方法のいくつかは、おそらく次のとおりです。

  • recipients: 1 つ以上の電子メール アドレスを使用します。これらのアドレスは、メールの配信先です。To: ヘッダーを設定します。
  • subject: メールの件名。Subject: ヘッダーを設定します。
于 2010-01-14T12:50:50.993 に答える
21

現在の Rspec 構文を使用して、最終的に次の構文を使用しました。

last_email = ActionMailer::Base.deliveries.last
expect(last_email.to).to eq ['test@example.com']
expect(last_email.subject).to have_content 'Welcome'

テストのコンテキストは、サインアップ後にウェルカム メールがユーザーに送信されることを確認する機能仕様でした。

于 2013-06-20T20:54:09.423 に答える
3

テスト フレームワークは、送信された電子メールに関する特定の条件をアサートできる優れたヘルパーが必要です。はい、ActionMailer.deliveries を使用して自分で行うこともできますが、すべてを 1 つのきちんとした小さなブロックにする必要があります。

于 2010-01-14T16:30:40.817 に答える
2

少し遅れていますが、他の人を助けるかもしれません:

Rspec/Minitest マッチャーと Cucumber ステップのコレクションであるEmail-specを使用できます。

于 2013-08-16T06:41:24.700 に答える
1

これが私が見つけた最良の方法です。

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)それだけです。

于 2010-05-12T03:23:27.090 に答える