[rspec-users] Asserting on a yield

Zach Dennis zach.dennis at gmail.com
Sun Mar 18 04:35:39 UTC 2012

On Sat, Mar 17, 2012 at 7:52 PM, Justin Ko <jko170 at gmail.com> wrote:
> On Mar 17, 2012, at 3:51 PM, Myron Marston wrote:
>> I've been thinking about this a bit ever since Zach Dennis brought up
>> the issue on another rspec-expectations ticket [1]. I've come up with
>> a proof-of-concept matcher that works pretty well, I think [2].
>> Here's how you use it:
>> expect { |b| 3.tap(&b) }.to yield_value(3)

Thanks for thinking about this some more. I don't think this will work
but I've commented on the Gist with a couple examples which help help
narrow in the implementation. St. Patty's night can be rough on the
mind so I'm not going to pretend that I can code right now.

I'll follow up tomorrow if someone doesn't beat me to it!


>> The argument passed to the expect block is a little weird, given that
>> no other block expectations take a block argument like this.  But I
>> don't see a way around it--for the matcher to detect whether or not an
>> argument is yielded (and what the argument is), it needs to control
>> the block passed to the method-under-test.  One big win here over some
>> of the other suggestions I've seen is that it works just fine with the
>> current rspec-expectations API (in contrast, some of the other
>> suggestions I've seen would special-case this matcher so that `expect`
>> takes multiple arguments for it to work).  I also like that it's built
>> as a block expectation; to me it is in the same category of matchers
>> as the change, raise_error and throw_symbol matchers: it's something
>> that happens as the result of running a bit of code.
>> If enough people like this we can work on getting it into rspec-
>> expectations as an officially supported matcher.  If we did, I'd want
>> to beef it up to be significantly more flexible:
>> # for methods that yield multiple arguments to the block...
>> # yield_value would accept a splat of args, and yield_values would
>> # be a more-grammatically-correct alias.
>> expect { |b| foo.fizz(&b) }.to yield_values(:a, 15)
>> # I'd advocate the matcher using the === operator w/ the given values,
>> # so either of these would work
>> expect { |b| "abc".gsub("a", &b) }.to yield_value(String)
>> expect { |b| "abc".gsub("a", &b) }.to yield_value(/a/)
>> # for cases where you need more control over matching the yielded
>> value, pass a block
>> expect { |b| foo.fizz(&b) }.to yield_value { |val| val.should
>> be_fizzy }
> Love this.
>> Thoughts?
>> [1] https://github.com/rspec/rspec-expectations/pull/119#issuecomment-4520633
>> [2] https://gist.github.com/2065445
>> _______________________________________________
>> rspec-users mailing list
>> rspec-users at rubyforge.org
>> http://rubyforge.org/mailman/listinfo/rspec-users
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users



More information about the rspec-users mailing list