9

I've been trying to stub open, the open-uri version, and I'm not succeeding.

I've tried doing the following but the request keeps going through:

Kernel.should_receive(:open).and_return("Whatever for now")

I've also tried to do

OpenURI::OpenRead.should_receive(:open).and_return("Whatever for now")

Since I tracked down that was where HTTP requests were made in OpenURI.

Thanks in advance for any suggestions!

gaqzi
  • 3,707
  • 3
  • 30
  • 30

3 Answers3

13

Here is what I do

class Gateway

  def do_something
    open('http://example.com').read
  end

end

In my spec i do the following:

describe 'communication' do

  it 'should receive valid response from example.com' do
    gateway = Gateway.new
    gateway.stub_chain(:open, :read).and_return('Remote server response')

    gateway.do_something.should == "Remote server response"
  end 

end
bonyiii
  • 2,833
  • 29
  • 25
9

I found a solution here on Stack Overflow after some more time on Google (I can't believe I didn't find this before).

Explanation taken from here and written by Tony Pitluga (not linkable).

If you are calling sleep within the context of an object, you should stub it on the object[...]
The key is, to stub sleep on whatever "self" is in the context where sleep is called.

So I did this and it all worked out:

let(:read) { mock('open') }

it "should return the new log-level when the log level was set successfully" do
    read.stub(:read).and_return('log-level set to 1')
    kannel.should_receive(:open).and_return(read)

    kannel.set_log_level(1).should == 1
  end
Community
  • 1
  • 1
gaqzi
  • 3,707
  • 3
  • 30
  • 30
  • Nice! I think it's reasonable to edit this and post it as the solution for `open()` and accept your own answer. It might be hard to find the `sleep()` article when stubbing `open()`. – wuputah Aug 30 '10 at 20:24
  • Very good point on stubbing on whatever the context of self is. This helped me solve a similar problem, thanks! – stuartc Apr 07 '11 at 13:43
  • I've updated your code. Explanation here: http://stackoverflow.com/a/11258596/608361 – Zsolt Jun 29 '12 at 08:43
1

I'd recommend using something to stub the network instead. I believe the current favorite for doing so is FakeWeb [docs]. You may also be interested in fakeweb-matcher for rspec.


Alas, I think FakeWeb might not work with open(), actually, it stubs Net::HTTP, so I'm not sure if that will work. Any chance of not using open()? :)

wuputah
  • 11,285
  • 1
  • 43
  • 60
  • `open()` is a perfect fit for where the code is going so using `Net:HTTP` directly would just feel wrong. :) I spent some more time on Google and found another Stack Overflow question that helped me out. But thanks for trying! – gaqzi Aug 30 '10 at 19:09