3

次のような RSpec テストがあります。

it "should ..." do
  # mailer = mock
  # mailer.should_receive(:deliver)
  Mailer.should_receive(:notification_to_sender)#.and_return(mailer)

  visit transactions_path
  expect do
    page.should_not have_css("table#transactions_list tbody tr")
    find('#some_button').click
    page.should have_css("table#transactions_list tbody tr", :count => 1)
  end.to change{Transaction.count}.by(1)
end

上部のコメント部分を削除すると、テストに合格します。しかし、コメント付きのセクションを配置すると (どのように記述すればよいか)、テストは失敗します。

私はネット上でいくつかのグーグルからコメントされた部分を手に入れましたが、それが何をしているのか、なぜこれが修正されるのかはよくわかりません. これなしで電子メールをテストするためのよりクリーンな方法があるはずです。

誰でも光を当てることができますか?ありがとう!

Rails 3 と rspec-rails 2.10.1 を使用しています

4

2 に答える 2

2

Mailer.notification_to_sender.deliverコントローラーを呼び出すか、バックグラウンド ジョブを呼び出している可能性があります。おそらく notification_to_sender もパラメーターを取ると思います。

とにかく、notification_to_senderMailer でメソッドを呼び出すと、そのメソッドMail::Messageを持つ のインスタンスが返さdeliverれます。Mailer.notification_to_senderも呼び出さずに単にdeliver実行している場合は、コメントを付けてそこにあるものを実行でき、すべて問題ありません。でも、あなたも電話していると思いますdeliver

その場合、失敗メッセージは次のようになります

NoMethodError:
  undefined method `deliver' for nil:NilClass

これはnil多くの場合、Ruby のデフォルトの戻り値であり、Rails も継承しているためです。mailer = mockとの部分を指定しないと.and_return(mailer)、コントローラーがテストのコンテキストで実行されると、notification_to_sender は nil を返し、コントローラーはdeliverその nil オブジェクトを呼び出そうとします。

コメントアウトした解決策は、notification_to_senderの戻り値 (通常は) をモックアウトし、そのメソッドが呼び出されることをMail::Message期待することです。deliver

于 2013-06-13T03:48:18.277 に答える
2

Mailer のインスタンスがクラスではなく notification_to_sender を受け取るようにしたいと思います。Rails API から

メーラー クラスをインスタンス化することはありません。むしろ、配信インスタンス メソッドは、deliver_ という単語で始まり、その後に配信するメーラー メソッドの名前が続くクラス メソッドに自動的にラップされます。上で定義した signup_notification メソッドは、Notifier.deliver_signup_notification を呼び出すことによって配信されます。

したがって、私は使用します

Mailer.any_instance.should_receive(:notification_to_sender)

また、最後に配信されたメッセージを取得する必要がある場合は、

ActionMailer::Base.deliveries.last

それはあなたの問題を解決するはずだと思います。

于 2012-06-05T05:46:04.610 に答える