ruby-on-rails rspec http-response-codes

ruby on rails - Cómo probar el estado de renderizado: 404 con Rails4 y RSpec cuando se usa rescue_from



ruby-on-rails http-response-codes (3)

Tengo una aplicación Rails4 con un ''PagesController''.

El método show muestra una excepción personalizada ''PageNotFoundError'' cuando no se encuentra una página.

En la parte superior del controlador rescue_from PageNotFoundError, with: :render_not_found

render not found es un método privado de PagesController y se parece a:

def render_not_found flash[:alert]=t(:page_does_not_exists, title: params[:id]) @pages = Page.all render :index, status: :not_found #404 end

El registro de rieles en modo de desarrollo muestra:

Started GET "/pages/readmef" for 127.0.0.1 at 2013-08-02 23:11:35 +0200 Processing by PagesController#show as HTML Parameters: {"id"=>"readmef"} .. Completed 404 Not Found in 14ms (Views: 12.0ms)

Por lo tanto, combina mi: status =>: not_found funciona, hasta ahora.

Cuando hago curl -v http://0.0.0.0:3000/pages/readmef curl logs

curl -v http://localhost:3000/pages/readmef * About to connect() to localhost port 3000 (#0) * Trying 127.0.0.1... * connected * Connected to localhost (127.0.0.1) port 3000 (#0) > GET /pages/readmef HTTP/1.1 > User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8x zlib/1.2.5 > Host: localhost:3000 > Accept: */* > < HTTP/1.1 404 Not Found < X-Frame-Options: SAMEORIGIN

Pero la siguiente prueba con RSpec falla:

it ''renders an error if page not found'' do visit page_path(''not_existing_page_321'') expect(response.status).to eq(404) within( ''.alert-error'' ) do page.should have_content(''Page not_existing_page_321 doesn/'t exist'') end end 1) PagesController renders an error if page not found Failure/Error: expect(response.status).to eq(404) expected: 404 got: 200

Todo se ve bien e incluso el test.log dice 404

$ tail -f log/test.log Started GET "/pages/not_existing_page_321" for 127.0.0.1 at 2013-08-03 09:48:13 +0200 Processing by PagesController#show as HTML Parameters: {"id"=>"not_existing_page_321"} Rendered pages/_page.haml (0.8ms) Rendered layouts/_navigation.haml (0.6ms) Rendered layouts/_messages.haml (0.2ms) Rendered layouts/_locales.haml (0.3ms) Rendered layouts/_footer.haml (0.6ms) Completed 404 Not Found in 6ms (Views: 4.5ms)

Probé diferentes servidores, WebRICK, Thin, unicorn. Todo funciona como se espera en el modo de desarrollo y producción. Incluso el test.log es correcto pero la prueba falla.

¿Alguien puede decirme por qué la prueba dice 200 en lugar de 404?


Aunque no estoy muy contento con esta solución, al menos esta es una solución:

Dividí la prueba en dos especificaciones separadas. Uno para probar el código de respuesta 404 (con GET en lugar de la visita) y otro para probar la alerta. La segunda prueba es necesaria porque get no render_views la vista, incluso si render_views se define encima del archivo de especificaciones.

it ''response with 404 if page not found'' do get :show, { controller: ''pages'', id: ''not_existing_page_321'' } expect(response.status).to eq(404) end it ''renders an error-message if page not found and shows index'' do visit page_path(''page_not_found'') within ''.alert-error'' do page.should have_content("Page page_not_found doesn''t exist") end end


El problema aquí es que usted está confundiendo las pruebas de características de Capybara y las pruebas del controlador RSpec. visit es un método proporcionado por Capybara y get / response se proporciona mediante las pruebas del controlador RSpec, no se pueden usar juntos .

Para probar esto como una sola prueba de controlador RSpec puede hacer:

it "returns a not found response" do get :show, { id: ''not_existing_page_321'' } expect(response.status).to eq(404) expect(response.text).to match(/Page page_not_found doesn''t exist/) end

(Nb. La línea de obtención es diferente de la que usted publicó. No he incluido el parámetro del controller como si colocara esto en spec/controllers/pages_controller_spec.rb donde no corresponde, no necesita eso)

O como una prueba única de Capibara:

it "renders a not found response" do visit page_path(''page_not_found'') expect(page.status_code).to eq(404) within ''.alert-error'' do expect(page).to have_content("Page page_not_found doesn''t exist") end end


Otro enfoque con RSpec 3+ sería probar una excepción:

it ''respond with 404 if page not found'' do expect{ get :show, :id => ''bad_id'' }.to raise_error(ActionController::RoutingError) end