Stubbing calls to the command line

I’m using a call to wget to download a large datafile (multiple
megabytes) having assumed this will be quicker than using open-uri.

How can I spec the behaviour? Ideally I’d also like to not be hitting
the internet every time I test!

in my_object_spec.rb

describe “.get_data” do
before(:each) do
@my_obj = MyObject.create(@valid_attributes)
end
it “should download the file” do
# behaviour goes here
end
end

in my_object.rb:

def get_data
wget --output-document=#{self.filename} #{self.file_uri}
end

I’ll be massively grateful for any help anyone can give me.

On Aug 14, 2008, at 3:42 AM, Andy C. wrote:

 @my_obj = MyObject.create(@valid_attributes)
 `wget --output-document=#{self.filename} #{self.file_uri}`

end

Use Kernel.stub!(:, "wget..."), and use Kernel.send(:, “wget”)
instead of literal backticks.

Scott

On Thu, Aug 14, 2008 at 3:42 AM, Andy C. [email protected]
wrote:

 @my_obj = MyObject.create(@valid_attributes)
 `wget --output-document=#{self.filename} #{self.file_uri}`

end

I’ll be massively grateful for any help anyone can give me.

I might end up with a separate object which managed making the wget
system call, and then I’ve have an integration-style test which
ensured it correctly downloaded a given passed in URL.

class MyObject
def get_data
WGet.download(“http://some/path”)
end
end

class WGet
def download(url)
wget #{url}
end
end

And I probably wouldn’t have a spec for WGet. I might make the
integration-style test a story. Perhaps when it ran I’d start
script/server in test mode, and then copy over a dummy file and pull
it down from “http://localhost:3000/public/dummy”.


Zach D.
http://www.continuousthinking.com

On Aug 14, 2008, at 11:58 PM, Andy C. wrote:

Scott T. wrote:

Use Kernel.stub!(:, "wget..."), and use Kernel.send(:, “wget”)
instead of literal backticks.

Oops. Meant Kernel.stub!(:`).with(“wget…”).and_return “some return
value”.

@my_obj.stub!(:`) …in the before block

Posted via http://www.ruby-forum.com/.


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users

Yeah - the top level should work, too:

main = self

main.should_receive(:`).with(“wget…”)

wget...

The downside is that you would need to pass around around your top
level instance of object (what I’ve been calling “main” here).

Scott

On Thu, Aug 14, 2008 at 5:09 PM, Zach D. [email protected]
wrote:

I might end up with a separate object which managed making the wget
system call, and then I’ve have an integration-style test which
ensured it correctly downloaded a given passed in URL.

+1

Scott T. wrote:

Use Kernel.stub!(:, "wget..."), and use Kernel.send(:, “wget”)
instead of literal backticks.

Interestingly this doesn’t quite work, but I used the principle.

The Kernel module is mixed into Object so when you use shellcommand... you can intercept the call on the object itself.

So I was able to:

@my_obj.stub!(:`) …in the before block

and

@my_obj.should_receive(:`, “wget…”) …in the test

and use the short form:

wget... …in the actual method.

Thanks for your help chaps.