Hi I''ve got code I want to intercept all errors (to report them) but re- raise them immediately. Currently the raise_error matcher doesn''t support matching against instances of exception classes, so I''ve done this to prove that the actual exception was re-raised: describe "when the update is unsuccessful" do class WeirdError < StandardError; end before(:each) do @error = WeirdError.new("Error") @server.stub!(:check_feeds).and_raise(@error) end it "should re-raise the exception" do lambda { @connection.receive_data("UPDATE\n") }. should raise_error(WeirdError) end end Few questions: Is this an appropriate behaviour to spec? If so, is this currently the best way to do it? If so, would exception instance matching be useful? Thanks Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
David Chelimsky
2008-Oct-07 14:33 UTC
[rspec-users] Specifying a specific error is re-raised
On Tue, Oct 7, 2008 at 8:57 AM, Ashley Moran <ashley.moran at patchspace.co.uk> wrote:> Hi > > I''ve got code I want to intercept all errors (to report them) but re-raise > them immediately. Currently the raise_error matcher doesn''t support > matching against instances of exception classes, so I''ve done this to prove > that the actual exception was re-raised: > > describe "when the update is unsuccessful" do > class WeirdError < StandardError; end > > before(:each) do > @error = WeirdError.new("Error") > @server.stub!(:check_feeds).and_raise(@error) > end > > it "should re-raise the exception" do > lambda { @connection.receive_data("UPDATE\n") }. > should raise_error(WeirdError) > end > end > > Few questions: > > Is this an appropriate behaviour to spec?Hmmm, should inappropriate behaviour be spec''d? :) Code examples are not politically correct. If you want your app to behave some way, there should be a way to spec it.> If so, is this currently the best way to do it? > > If so, would exception instance matching be useful?Check out http://rspec.info/rdoc/classes/Spec/Matchers.html#M000434 I see that it is incomplete, because you can use just a string or regexp if you want (w/o the error itself). I''ll adjust for the next release. Regardless, if you really care about the specific instance you can do this: lambda { @connection.receive_data("UPDATE\n") }.should raise_error {|error| error.should equal(@error)} If what you care about is the message, you can expect specific messages using strings or regexps: lambda { @connection.receive_data("UPDATE\n") }.should raise_error("with this message") lambda { @connection.receive_data("UPDATE\n") }.should raise_error(/with a message containing this/) lambda { @connection.receive_data("UPDATE\n") }.should raise_error(OfThisErrorType, "with this message") lambda { @connection.receive_data("UPDATE\n") }.should raise_error(OfThisErrorType, with a message containing this/) Cheers, David> > Thanks > Ashley
On 7 Oct 2008, at 15:33, David Chelimsky wrote:> Regardless, if you really care about the specific instance you can > do this: > > lambda { > @connection.receive_data("UPDATE\n") > }.should raise_error {|error| error.should equal(@error)} > > If what you care about is the message, you can expect specific > messages using strings or regexps:Thanks - that snippet does exactly what I want. Basically I want tee pipe-fitting for errors - the code now looks like this: class Connection < EventMachine::Connection attr_accessor :server def receive_data(data) if data.chomp == "UPDATE" handle_update else send_data("ERROR: Unknown command\n") end end def unbind raise @error if @error end private def handle_update server.check_feeds rescue StandardError => @error send_data("ERROR: #{@error.to_s}\n") close_connection_after_writing else send_data("OK\n") end end So I don''t care about the exception beyond extracting enough data to feed back through the socket. Cheers Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/