2016-04-14 5 views
0

: Rspec: Henüz mevcut olmayan bir kaynakla nasıl elde edilmeyi bekliyoruz? Bir kaynak RequestOffer arayıp parametre olarak oluşturulan bir kaynağı kullanan ActionMailer e-posta göndermek yaratıyorum bir post isteği aracılığıyla adında bir eylemle

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

benim denetleyicisi Spec, bunu test etmek istiyorum

benim RequestOfferMailer, resource @request_offer parametresiyle email_team yöntemini kullanarak çağrılır.

Kullanıcı istediğimde (XXX). (YYY) .with (ZZZ) ile almak istediğimde, tek yolu POST isteğini yapmadan önce beklentimi bildirmekti. Ancak, ZZZ bu POST isteğiyle yaratıldı, bu yüzden beklentimi önceden belirlemem mümkün değil.

# 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 

Bu sorunun nasıl çözüleceği hakkında bir fikriniz var mı?

cevap

1

: Örneğin:

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

ben RSpec 3,0 dokümanlar bu seçeneği buldum. Bunu example_doubles kullanarak yapabilir ve ifadeleri izin verebilirsiniz. İşte bu anahtarı oluşturmak niyetinde modelin bir örnek duble ilan etmek 'izin' kullanıyor

sizin amaçlı

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 

uzatmak ister olabilecek bir örnek. Sınıftaki beklentileri ayarlayarak, örneğinizi testin içine ikiye katlayabilir ve DB'den izole edebilirsiniz. Önceden blokta 'izin ver' çağrısının, mailer nesnesinde beklentileri belirleyen daha sonraki özellikleri sunması gerektiğine dikkat edin; İlk testte 'bekle' araması, arama hakkında hala iddialarda bulunabilecektir.

1

Argümanın RequestOffer örneğinin olduğundan emin olmak yeterli olur mu? Daha sonra instance_of eşleştiriciyi kullanabilirsiniz. Bu o zaman DB'den kontrolör testini izole edebilecek bir fonksiyonel testi ise https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/setting-constraints/matching-arguments

+0

İdeal olarak bundan daha fazlasını test ederim. Bununla birlikte, bağlantınız bir çözüm olabilecek bir şey sunar, kullanıcı bir müşteri eşleştiricisi: https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/setting-constraints/matching-arguments#using-a- özel-matcher Ben de bir RequestOffer bir örneğini de e-posta şablonunda gerekli benim durumumda telefon_numarası ve e-posta gibi, önemli öznitelikleri eşit olduğunu kontrol ederek tanımlayabilirsiniz. Birisinin daha basit bir çözümü olup olmadığını görelim, ama ipucu için şimdiden teşekkür ederim! –

İlgili konular