btakita / rr

RR (Double Ruby) is a test double framework that features a rich selection of double techniques and a terse syntax.
http://github.com/rr/rr
MIT License
501 stars 58 forks source link

Chained yields do not work #84

Open dipth opened 12 years ago

dipth commented 12 years ago

According to stub_spec.rb it should be possible to chain multiple calls to yields to make the stub invoke the block for each call to `yields with the specified arguments.

context "when yields calls are chained" do
  it "yields several times" do
    called_from_block = mock!.foo(1).once.then.foo(2).once.subject
    block_caller = stub!.bar.yields(1).yields(2).subject
    block_caller.bar { |argument| called_from_block.foo(argument) }
  end
end

This doesn't seem to work in our production app though. I've tried copying over the exact test and it fails with the following error:

  1) FinanceExporting::Exporter#write_sales_events appends the entries to CSV
     Failure/Error: called_from_block = mock!.foo(1).once.then.foo(2).once.subject
     RR::Errors::TimesCalledError:
       foo(1)
       Called 0 times.
       Expected 1 times.
     # ./spec/models/finance_exporting/exporter_spec.rb:65:in `block (3 levels) in <top (required)>'
     # ./spec/support/database_cleaner.rb:9:in `block (2 levels) in <top (required)>'

When I dig depper into it, I can see that it only invokes the block with the second argument.

We're using Ruby 1.9.3-p125 - but the funny thing is that I've run the rr test suite with the exact same ruby version where it completes successfully.

mcmire commented 11 years ago

Sorry for the late reply here, I just took over this project and am reviewing old issues.

First I believe you may need to do this:

context "when yields calls are chained" do
  it "yields several times" do
    called_from_block = mock!.foo(1).once.then.foo(2).once.subject
    block_caller = stub!.bar.yields(1).then.bar.yields(2).subject
    block_caller.bar { |argument| called_from_block.foo(argument) }
  end
end

Second, you're only calling the #bar method on block_caller once so I don't know why you have two yields there.

I don't know if you remember this issue still or are even concerned anymore but if so can you give me a failing test? Thanks.