Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I stub "raise" in Ruby?

I have a class called RemoteError with a self.fatal method on it. This methods job is basically to catch an exception, send the details of the exception to a server and then propagate the exception in order to kill the program.

class RemoteError
  def initialize(label, error)
    @label = label
    @error = error
  end

  def self.fatal(label, error)
    object = new(label, error)
    object.send
    raise error
  end

  def send
    # send the error to the server
  end
end

I'm trying to write tests for the RemoteError.fatal method. This is difficult because of the call to raise within the method. Every time I run my tests, raise obviously raises an exception and I can't test that send was called.

  describe "fatal" do
    it "should send a remote error" do
      error = stub
      RemoteError.stub(:new) { error }
      error.should_receive(:send)

      RemoteError.fatal(stub, stub)
    end
  end

Is there a way that I can stub or somehow circumvent raise for this specific test?

like image 936
David Tuite Avatar asked Nov 23 '25 23:11

David Tuite


1 Answers

You could wrap the method that raises the error in a lambda...

it "should send a remote error" do
  ...

  lambda { RemoteError.fatal(stub, stub) }.should raise_error(error)
end    

This essentially allows the method to be called, and you get the return value or raised error from it, which you then assert against with .should raise_error(error). This also makes is so that if no error is raised from that call, the test will fail normally.

To say it another way, you don't need, nor want, to stub raise. Simply wrap it in a lambda and your code will continue to execute, you should be able to make sure that your message is sent, and your test won't exit/crash.

like image 179
jefflunt Avatar answered Nov 25 '25 15:11

jefflunt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!