-->

RSpec — test if method called its block parameter

2019-02-23 08:25发布

问题:

I have a method that takes block of code as an argument. The problem is: how to test using RSpec if this method called the block?

The block may be evaluated in any scope the method needs, not necessarily using a yield or block.call. It be passed to another class, or evaluated it in an anonymous class object or somewhere else. For the test to pass it is enough to evaluate the block somewhere as a result of the method call.

Is there a way to test something like this using RSpec?


See also this for more complex case with lets and mocks.

回答1:

I usually do something like

a = 1
b.go { a = 2}
a.should == 2


回答2:

I like using throw instead of raise for this sort of problem, because it can't be rescued be an arbitrary rescue handler. So it might look like this:

my_proc = proc { throw :my_proc_was_called }
expect {
  my_proc.call
}.to throw_symbol :my_proc_was_called


回答3:

Thanks to Dave Newton's suggestion in the comment above I did something like this:

 it "should run block defining the node" do
   message="This message is raised if block is properly evaluated."
   expect do
     node do
       raise message
     end 
   end.to raise_error message
 end

In case of error this prints message:

 Failure/Error: expect do
   expected Exception with "This message is raised if block is properly evaluated." but nothing was raised

Which I find informative enough.

Thanks again for help!