[rspec-users] Verifying that a block calls a method
Scott Taylor
mailing_lists at railsnewbie.com
Tue Apr 17 22:07:11 EDT 2007
On Apr 17, 2007, at 1:03 PM, nicholas a. evans wrote:
> On 4/17/07, Scott Taylor <mailing_lists at railsnewbie.com> wrote:
>> def my_fun
>> my_fun2 do
>> raise Error
>> end
>> end
>>
>> I know that I can verify that the method receives my_fun2. How can I
>> mock/stub out the example to verify that it calls raise Error?
>
> Have you tried "should raise_error(...)"?
>
> lambda { my_fun }.should raise_error
Sure, I have - the problem is that the method my_fun2 only raises
error under certain conditions - if for instance, Control-C is
pressed. It is quite different from a block like the following, in
which the method call is guaranteed to execute:
def my_fun3
[1,2,3].each { |x| puts x }
end
Then a spec like this should work just fine:
describe "my_fun3" do
it "should call puts on the first element" do
obj.should_receive(:puts).with(1)
obj.my_fun3
end
end
The example shows that the second method being called (puts), should
be mocked (because you don't actually want to dump the numbers 1-3 to
the terminal during your specs.
How do you mock out my_fun3? The only clear advise I've gotten is to
pass my_fun3 a stream, and let the default parameter be a STDOUT
stream, like so:
def my_fun3(stream = STDOUT)
[1,2,3].each { |x| stream.puts x }
end
describe "my_fun3" do
setup do
@io = mock(io)
@io.stub!(:puts).and_return @io
end
it "should call puts on the first element" do
@io.should_receive(:puts).with(1)
obj.my_fun3
end
end
Every time you use this method in production, you just leave off the
parameter, and it defaults to calling puts (as normal). The stream
parameter is only used during testing. This is a little disturbing,
because now you have to change the source to fit your tests for code
that will never be used in production. Luckily it's not a big
change, so it's probably not a big deal.
The specific example that I'm dealing with raises an error *only*
when pressing ^C.
def add_sigint_handler
trap("INT") { raise Interrupt }
end
Raise only gets called if ^C (or an INT signal) is received. So how
would I spec that method?
The one thought that I had was that I should be able to pass the
block to the method as the last parameter. Unfortunately, this
doesn't seem to work.
Any other thoughts?
Thanks,
Scott Taylor
>
> http://rspec.rubyforge.org/rdoc/classes/Spec/Matchers.html#M000290
>
> --
> Nick
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
More information about the rspec-users
mailing list