Returning a StringIO object from a stub

View: New views
3 Messages — Rating Filter:   Alert me  

Returning a StringIO object from a stub

by JGailor :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I'm trying to stub File.new so I can return a StringIO object from it
to set some expectation and make sure the subject under test is
behaving correctly, but calling readline() on the StringIO object in
the subject always returns nil.  What's strange is that calling read()
returns the entire set of data in the StringIO object.  Additionally,
calling readline() on the StringIO object from inside the test works
fine as well.

data = <<-DATA
 ...
DATA

faux_file = StringIO.new(data)
File.stub!(:new).and_return(faux_file)
faux_file.should_receive(:readline).exactly(x).times
Subject.new("").parse


I'm using rspec 1.2.9 (this is not testing a rails app).  Can anyone
give me any advice on why this might be?

Thanks,

Jeremy
_______________________________________________
rspec-users mailing list
rspec-users@...
http://rubyforge.org/mailman/listinfo/rspec-users

Re: Returning a StringIO object from a stub

by Paul Hinze :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

JGailor <jeremy@...> on 2009-11-11 at 16:11:

> I'm trying to stub File.new so I can return a StringIO object from it
> to set some expectation and make sure the subject under test is
> behaving correctly, but calling readline() on the StringIO object in
> the subject always returns nil.
>
> data = <<-DATA
>  ...
> DATA
>
> faux_file = StringIO.new(data)
> File.stub!(:new).and_return(faux_file)
> faux_file.should_receive(:readline).exactly(x).times
> Subject.new("").parse

As soon as you call `should_receive(:readline)`, you are not only setting an
expectation for that method to be received but also stubbing out the method.

Here's a bit more in-depth discussion of that:

http://axonflux.com/rspecs-shouldreceive-doesnt-ac

That link also discusses why that might be a good idea -- it keeps specs simple.

So you've got two options,

(1) If you've got your heart set on counting the number of calls to readline
    you can do something like the following:

    faux_file.should_receive(:readline).exactly(x).times.and_return(*data.readlines)

        Which, as you can see, is basically a funky re-implementation of
    StringIO#readline, but it should do the trick.

(2) I would encourage you to consider this: rather than asserting that every
        line is _read_, simply verify that the result of your Subject#parse method
        includes data that would _prove_ that each line has been read.  That way
        you're testing behavior rather than implementation.

Cheers,

Paul
_______________________________________________
rspec-users mailing list
rspec-users@...
http://rubyforge.org/mailman/listinfo/rspec-users

Re: Returning a StringIO object from a stub

by JGailor :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks Paul,

As soon as I read the first part of your message I had one of those
face-palm moments.  Thanks for your help.  In the case of this
expectation, I'm not sure which path I'll take as this particular test
is looking for it to read a certain number of lines of input before
finding the target line.
_______________________________________________
rspec-users mailing list
rspec-users@...
http://rubyforge.org/mailman/listinfo/rspec-users