2017-03-02 48 views
1

我需要確保運行導入程序會導致發送電子郵件。Rails,RSpec:如何測試,是否觸發特定的郵件程序

這是我走到這一步:

describe '#import' do 
    it 'triggers the correct mailer and action', :vcr do 
    expect(OrderMailer).to receive(:delivery_confirmation).with(order) 

    Importer.new(@file).import 
    remove_backed_up_file 
    end 
end 

它失敗:

pry(#<ActiveRecord::ConnectionAdapters::TransactionManager>)> error 
=> #<NoMethodError: undefined method `deliver_now' for nil:NilClass> 

這顯然不能工作了,因爲我期待梅勒類接收(實例)方法調用。但是,我怎樣才能獲得將接收呼叫的郵件實例?你如何測試一個單元的方法觸發某個郵件程序?

回答

1

如果我有你的權利,

expect_any_instance_of(OrderMailer).to receive(:delivery_confirmation).with(order) 

將測試將接收呼叫的郵件實例。

爲了更精確,你可能要設置測試用的OrderMailer特定實例(假設order_mailer)和寫您的期望通過以下方式

expect(order_mailer).to receive(:delivery_confirmation).with(order) 
+0

我怎樣才能得到最終會收到呼叫的實例?僅僅實例化這個類並不能保證這個實例將被Rails使用,對嗎? – Flip

+0

對不起,我沒有關於郵件程序測試的經驗,也無法回答你應該怎麼做。但一般來說,您可以用'OrderMailer'實例來存儲'OrderMailer.new'或'OrderMailer.create',以確保您的測試將完全處理您的實例。例子是'allow(OrderMailer).to接收(:create).and_return(order_mailer)'。 'order_mailer'必須在那個時候創建​​。 – VAD

+0

好的,很酷。謝謝。 'expect_any_instance_of'完美運行。 – Flip

2

我假設在現實中delivery_confirmation方法返回一個Mail目的。問題是ActionMailer將調用郵件對象的deliver方法。你已經設定了一個期望值,用於保存delivery_confirmation方法,但是你沒有指定什麼應該是返回值。試試這個

mail_mock = double(deliver: true) 
# or mail_mock = double(deliver_now: true) 
expect(mail_mock).to receive(:deliver) 
# or expect(mail_mock).to receive(:deliver_now) 
allow(OrderMailer).to receive(:delivery_confirmation).with(order).and_return(mail_mock) 
# the rest of your test code 
相關問題