Rails ActiveSupport: How to assert that an error is raised?
Asked Answered
G

2

60

I am wanting to test a function on one of my models that throws specific errors. The function looks something like this:

def merge(release_to_delete)
  raise "Can't merge a release with itself!" if( self.id == release_to_delete.id )
  raise "Can only merge releases by the same artist" if( self.artist != release_to_delete.artist   )
  #actual merge code here
end

Now I want to do an assert that when I call this function with a parameter that causes each of those exceptions, that the exceptions actually get thrown. I was looking at ActiveSupport documentation, but I wasn't finding anything promising. Any ideas?

Greenberg answered 11/8, 2010 at 2:47 Comment(0)
C
129

So unit testing isn't really in activesupport. Ruby comes with a typical xunit framework in the standard libs (Test::Unit in ruby 1.8.x, MiniTest in ruby 1.9), and the stuff in activesupport just adds some stuff to it.

If you are using Test::Unit/MiniTest

assert_raise(Exception) { whatever.merge }

if you are using rspec (unfortunately poorly documented, but way more popular)

lambda { whatever.merge }.should raise_error

If you want to check the raised Exception:

exception = assert_raises(Exception) { whatever.merge }
assert_equal( "message", exception.message )
Coreycorf answered 11/8, 2010 at 2:54 Comment(3)
Thanks! I had to use "RuntimeError" instead of exception though, like this: assert_raise( RuntimeError ){ artist1.merge(artist1) } This guide was extremely helpful: guides.rubyonrails.org/testing.htmlGreenberg
@spilliton: Thats because the Ruby interpreter treats the code above as assert_raise(Exception() { whatever.merge }), i.e. it looks for a method called Exception which is called with the given block. Adding the parentheses resolves that ambiguity. (Already fixed the answer)Acatalectic
In rspec 3, use expect { whatever.merge }.to raise_error (relishapp.com/rspec/rspec-expectations/v/3-1/docs/…)Strudel
A
18

To ensure that no exception is raised (or is successfully handled) do inside your test case:

assert_nothing_raised RuntimeError do
  whatever.merge
end

To check that error is raised do inside your test case:

assert_raise RuntimeError do
  whatever.merge
end

Just a heads up, whatever.merge is the code that raises the error (or doesn't, depending on the assertion type).

Archon answered 4/12, 2013 at 5:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.