I want to use RSpec mocks to provide canned input to a block.
Ruby:
class Parser attr_accessor :extracted def parse(fname) File.open(fname).each do |line| extracted = line if line =~ /^RCS file: (.*),v$/ end end end
RSpec:
describe Parser before do @parser = Parser.new @lines = mock('lines') @lines.stub!(:each) File.stub!(:open).and_return(@lines) end it 'should extract a filename into extracted' do linetext = [ 'RCS file: hello,v\n', 'bla bla bla\n' ] # HELP ME HERE ... # the :each should be fed with 'linetext' @lines.should_receive(:each) @parser.should_receive('extracted=') @parser.parse('somefile.txt') end end
It’s a way to test that the internals of the block work correctly by passing fixtured data into it. But I can’t figure out how to do the actual feeding with RSpec mocking mechanism.
update: looks like the problem was not with the linetext, but with the:
@parser.should_receive('extracted=')
it’s not the way it’s called, replacing it in the ruby code with self.extracted= helps a bit, but feels wrong somehow.
I don’t have a computer with Ruby & RSpec available to check this, but I suspect you need to add a call to
and_yieldscall [1] on the end of theshould_receive(:each). However, you might find it simpler not to use mocks in this case e.g. you could return aStringIOinstance containinglinetextfrom theFile.openstub.[1] http://rspec.rubyforge.org/rspec/1.1.11/classes/Spec/Mocks/BaseExpectation.src/M000104.html