Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to assert that a Rails method will not throw a NoMethodError

In my Rails application I am doing a unit test where I expect an error when calling a certain method.

test "sending a logout request while not logged should not return an error" do
  assert_nothing_raised do
    do_a_logout
  end
end

Problem is that the test keeps reporting as Error instead as of Failure when do_a_logout errors out.

The error is NoMethodError: NoMethodError: undefined method 'forget' for nil:NilClass

It comes from this method two or three levels below the do_a_logout call

def forget user
  user.forget
  cookies.delete :user_id
  cookies.delete :remember_token
end

Here, the error I am expecting is for user to be nil and fail when calling forget. How can I make the test report a Failure instead of an Error?

like image 671
William Troy Avatar asked Oct 28 '25 00:10

William Troy


1 Answers

You want to use assert_raise with the exception class you're expecting:

assert_raise(NoMethodError) { do_a_logout }

ETA: If you want to test that no error was raised, you can use assert_nothing_raised:

assert_nothing_raised { do_a_logout }
assert_nothing_raised(NoMethodError) { do_a_logout }

However as pointed out on SO and elsewhere, there is no good reason to use this assertion, because its redundant: you never expect an error to be raised, unless you specify otherwise.

Moreover, it gives a less helpful failure than simply running the spec without the assertion. In particular, running with assert_nothing_raised when an error occurs will give you a backtrace only to the assert_nothing_raised call, while running the spec without this assertion will give a backtrace to the actual error that's occurring.

like image 79
eirikir Avatar answered Oct 29 '25 18:10

eirikir