2014-01-26 112 views
2

我有一個使用'open-uri'的郵件程序。如何模擬呼叫開放 - uri

require 'open-uri' 
class NotificationMailer < ActionMailer::Base 

    def welcome(picasa_picture) 
    picture = picasa_picture.content.src 
    filename = picture.split('/').last 
    attachments.inline[filename] = open(picture).read 
    mail(
     to: '[email protected]', 
     from: '[email protected]', 
     subject: 'hi', 
    ) 
    end 
end 

但是當我嘗試和測試任何類,我得到這個錯誤:

SocketError: 
    getaddrinfo: nodename nor servname provided, or not known 

我發現這個職位的SO:How to rspec mock open-uri並認爲這將幫助。我給了這個嘗試:

let(:pic_content) { double(:pic_content, src: 'http://www.picasa/asdf/asdf.jpeg') } 
let(:picture) { double(:picture, content: pic_content) } 
let(:open_uri_mock) { double(:uri_mock, read: true) } 

subject { described_class.welcome(picture) } 

it 'renders email address of sender' do 
    subject.stub(:open).and_return(open_uri_mock) 
    subject.from.should == [ sender_address ] 
end 

我也嘗試了'should_receive'而不是'存根',但它沒有幫助。如何禁止open-uri'open'方法,使其(1)不會嘗試去互聯網和(2)不打破我的測試?

+0

我不知道,據我可以告訴你,你磕碰這裏合適的對象的open方法 –

+0

'在你調用方法後重新存根,所以它不會工作 –

+0

這篇文章似乎認爲你在內核上做了stub:https://stackoverflow.com/questions/3603256/rspec-how-to-stub-open –

回答

1

爲什麼不重構:

require 'open-uri' 
class NotificationMailer < ActionMailer::Base 

    def welcome(picasa_picture) 
    picture = picasa_picture.content.src 
    filename = picture.split('/').last 
    attachments.inline[filename] = open_and_read(picture) 
    mail(
     to: '[email protected]', 
     from: '[email protected]', 
    subject: 'hi', 
    ) 
    end 

    def open_and_read(picture) 
    open(picture).read 
    end 

end 

然後你可以存根和測試:

subject { NotificationMailer } 

before do 
    subject.stub(:open_and_read).and_return(:whatever_double_you_want) 
    subject.welcome(picture) 
end 

it 'renders email address of sender' do 
    subject.from.should == [ sender_address ] 
end 
+1

美麗。好的解決方案我不得不用'describe_class.any_instance.stub(:open_and_read).with(picture).and_return('picture_as_url')'來使它工作,但所有的測試都通過了。謝謝! –

+0

可能也想用更新的rspec語法:'''expect(subject.from).to eq([sender_address])''' –