2016-04-14 5 views
0
私は、リソースを作成していますポストの要求を介しというアクションで

がRequestOfferを呼び出し、パラメータとして作成されたリソースを使用してactionmailerのに電子メールを送信:Rspec:まだ存在しないリソースでの受信を期待するには?

@request_offer = RequestOffer.new(request_offer_params) 
if @request_offer.save 
    RequestOfferMailer.email_team(@request_offer).deliver_later 
end 

、私は私のことをテストしたい場合は、私のコントローラの仕様RequestOfferMailerは、リソース@request_offerをパラメータとしてメソッドemail_teamを使用して呼び出されます。

(YYY).with(ZZZ)を受け取るには(XXX)。私が見つけた唯一の方法は、POSTリクエストを行う前に私の期待を宣言することでした。しかし、ZZZはこのPOST要求によって作成されるので、私は前もって予想を設定する方法がありません。

# Set expectation first 
message_delivery = instance_double(ActionMailer::MessageDelivery) 

# ZZZ used in .with() does not exist yet, so it won't work 
expect(RequestOfferMailer).to receive(:email_team).with(ZZZ).and_return(message_delivery) 
expect(message_delivery).to receive(:deliver_later) 

# Make POST request that will create ZZZ 
post :create, params 

どのようにこの問題を解決するには?

答えて

1

:例えば:

expect(RequestOfferMailer).to receive(:email_team).with(instance_of(RequestOffer)).and_return(message_delivery) 

IはRSPEC 3.0ドキュメントには、このオプションを発見しました。これを行うには、instance_doublesとlet文を使用します。このための鍵は、作成しようとするモデルのインスタンスのダブルを宣言するために「聞かせて」使用しているここでは、あなたの目的に

describe '/request_offers [POST]' do 
    let(:request_offer) { instance_double(RequestOffer, save: true) } 

    before do 
    allow(RequestOffer).to receive(:new). 
     with(...params...). 
     and_return(request_offer) 
    end 

    it 'should instantiate a RequestOffer with the params' do 
    expect(RequestOffer).to receive(:new). 
     with(...params...). 
     and_return(request_offer) 
    post '/request_offers', {...} 
    end 

    it 'should email the request offer via RequestOfferMailer' do 
    mailer = instance_double(ActionMailer::MessageDelivery) 

    expect(RequestOfferMailer).to receive(:email_team). 
     with(request_offer).and_return(mailer) 

    post '/request_offers', {...} 
    end 
end 

を拡張するようなことが一例です。クラスに期待を設定することで、インスタンスをテストに二重に注入し、DBから分離することができます。 beforeブロックの 'allow'コールは、メーラーオブジェクトの期待値を設定する後のスペックを提供するためのものであることに注意してください。最初のテストでの 'expect'コールは引き続きコールのアサーションを行うことができます。

1

引数がRequestOfferのインスタンスであることを確認するだけで十分でしょうか?その後、instance_ofマッチャーを使用することができます。これは、私はDBからコントローラ試験を隔離なる機能試験の場合https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/setting-constraints/matching-arguments

+0

私は理想的にそれ以上のテストをします。しかし、あなたのリンクは、ソリューション、ユーザーの顧客マッチャーを提供する何かを提供しています:https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/setting-constraints/matching-arguments#using-a-カスタムマッチャー私は、それが重要なアトリビュートが同じであることによって、それがRequestOfferのインスタンスであることをチェックすることを定義することができます。phone_numberと、メールのテンプレートに必要な私のメール。誰かがもっと簡単な解決策を持っているかどうかを見てみましょうが、ヒントのために既にありがとう! –

関連する問題