Sometimes you need to test the status code of a response in a controller, request, or feature spec. With the rspec-rails gem this can be done cleanly using the have_http_status matcher.

have_http_status can take three different arguments:

  1. numeric code (200, 404, etc)
  2. status name as defined in Rack::Utils::SYMBOL_TO_STATUS_CODE (:ok, :not_found, etc)
  3. generic status type (:success, :missing, :redirect, or :error)

This means that these are actually different:

it { is_expected.to have_http_status(:ok) }
it { is_expected.to have_http_status(:success) }

Because :ok, as defined in Rack::Utils::SYMBOL_TO_STATUS_CODE, only matches status 200 while :success is a generic status type that matches all “successful” status types.

According to the RSpec source code, the generic status types map to the following status codes:

case expected
when :error, :server_error
  "5xx"
when :success, :successful
  "2xx"
when :missing, :not_found
  "404"
when :redirect
  "3xx"
end