How to test 404 Sinatra::NotFound errors with Rack::Test?

2k Views Asked by At

I have an application that raises 404 Sinatra::NotFound errors on production when the route is missing.

However, the following test passes:

it 'should not raise error' do
  expect{ get '/unknown_path' }.to_not raise_error
end

Why don't 404 Sinatra::NotFound errors get raised in the test?

The following does raise the error and cause the test to fail:

get '/unknown_path' do
  raise 'error'
end

How to test for 404 Sinatra::NotFound errors?

2

There are 2 best solutions below

0
On

Try this:

get '/unknown_path'
assert_equal last_response.status, 404
6
On

The issue is that get /unknown_path' is not actually raising an error – it's only receiving a 404 request.

From Sinatra: README

The error handler is invoked any time an exception is raised from a route block or a filter. The exception object can be obtained from the sinatra.error Rack variable...

Your test is testing for an actual error (this is what raise_error does), while Sinatra is squashing the error – otherwise, every time someone 404'd the server would crash!

Check out the Sinatra testing guide for better direction on forming your tests. The basic idea is that using get ... in a test sets the last_response local variable, which can then be tested for equality, etc.

last_response has a status attribute, so (like was mentioned in another answer) you can just test to make sure that last_response.status equals 404.

Edit:

I wasn't really clear about this. In testing mode, the application does actually raise errors.

From Sinatra Settings

raise_errors raise exceptions (will stop application). Enabled by default when environment is set to "test", disabled otherwise.

So you don't actually want to raise just any error, but raise Sinatra::NotFound.new("Not found!") to raise the specific type of error. The Sinatra::NotFound error will trigger the 404 handler. Sinatra Error Handling