How to use assert_raise to test for an error in Ruby?

assert, factorial, ruby, testing, unit-testing

Solution

Assuming that you are using minitest, if you are trying to test that an error is raised you can use the `asert_raises` method. (Notice the plural form)

def test_negative
  assert_raises <expected error name> do
    factorial(-1)
  end
end

However, no error will be raised with the example you presented so far.

Additional information:

This example `(1..-5).inject(:*)` will evaluate to nil. You will not get an error. I assume your `test_negative` should assert that the return value is `1` given your current implementation.

Also if you would like to give inject a default value you can pass it as the first argument: `(1..n).inject(1, :*)`. This way you avoid using the `||` operator.

A great suggestion from @ArupRakshit below is to raise your own `NegativeFactorial` exception. You will need to define it first.

class NegativeFactorial < StandardError; end

Then you can use it in your factorial method like this:

def factorial(n)
  raise NegativeFactorial, "The number provided is negative." if n < 0
  (1..n).inject(1, :*)
end

And you can implement your `test_negative` to assert that the exception has been raised.

def test_negative
  assert_raises NegativeFactorial do
    factorial(-1)
  end
end

Problem

I have the programs `factorial.rb` and `test_factorial.rb`. The former looks like this: ``` def factorial(n) (1..n).inject(:*) || 1 end ``` `test_factorial` looks like this: ``` def test_number assert_equal 6, factorial(3),"3! should be 6" end def test_zero assert_equal 1, factorial(0), "0! should be 1" end ``` I need to add another method, `test_negative` to the test file that confirms an error is raised when the factorial is negative. I looked at the documentation but still don't understand what I'm supposed to do. Do I have to specify a certain type of error after `assert_raise`? Do I need to add code to `factorial.rb` or not since the error is generated automatically?

Original source