constantine1
constantine1

Reputation: 427

How to test a function which takes a block with rspec

I have a function, which accepts a block, opens a file, yields and returns:

def start &block
    .....do some stuff
    File.open("filename", "w") do |f|
        f.write("something")
        ....do some more stuff
        yield
    end
end

I am trying to write a test for it using rspec. How do I stub File.open so that it passed an object f (supplied by me) to the block instead of trying to open an actual file? Something like:

it "should test something" do
    myobject = double("File", {'write' => true})
    File.should_receive(:open).with(&blk) do |myobject|
        f.should_receive(:write)
        blk.should_receive(:yield) (or somethig like that)
    end
end

Upvotes: 15

Views: 12565

Answers (2)

Amir
Amir

Reputation: 1872

I think what you're looking for are yield matchers, i.e:

it "should test something" do
  # just an example
  expect { |b| my_object.start(&b) }.to yield_with_no_args
end
  

Upvotes: 7

La-comadreja
La-comadreja

Reputation: 5755

Your other choice is to stub :open with a new object of File, as such:

file = File.new
allow(File).to receive(:open) { file }
file.each { |section| expect(section).to receive(:write) }
# run your method

Upvotes: 1

Related Questions