[rspec-users] Returning a StringIO object from a stub

Paul Hinze
2009-11-12T03:43:10Z

JGailor <jeremy at infinitecube.com> 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