Reputation: 22653
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?
Upvotes: 2
Views: 722
Reputation: 33954
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.
Upvotes: 9
Reputation: 13719
In your tests you are testing the method that raises an error and this is an expected result of method execution. You should write expectation for exception with this syntax:
lambda{ RemoteError.fatal(stub, stub) }.should raise_error
In this case your spec will fail if exception won't be raised and also will fail if all other expectations (like should_receive(:sen)
) won't be met.
Upvotes: 3