2014-01-26 60 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])''' –