2012-06-08 17 views
17

No sé lo que estoy haciendo mal, pero cada vez que trato de probar una redirección, aparece este error: "@request debe ser un ActionDispatch :: solicitud"Cómo probar una redirección con Rspec y Capybara

context "as non-signed in user" do 
    it "should redirect to the login page" do 
    expect { visit admin_account_url(account, host: get_host(account)) }.to redirect_to(signin_path) 
    end 
end 
1) AdminAccountPages Admin::Accounts#show as non-signed in user should redirect to the login page 
    Failure/Error: expect { visit admin_account_url(account, host: get_host(account)) }.to redirect_to(signin_path) 
    ArgumentError: 
     @request must be an ActionDispatch::Request 
    # ./spec/requests/admin_account_pages_spec.rb:16:in `block (4 levels) in <top (required)>' 

estoy usando RSpec-carriles (2.9.0) con Carpincho (1.1.2) y Rails 3.2. Agradecería que alguien también pudiera explicar por qué sucede esto; ¿Por qué no puedo usar el esperar de esa manera?

+0

Tal vez me falta algo, pero ¿qué pasa con 'assert_redirected_to'? –

+0

@JosephWeissman, me sale el mismo error! – Mohamad

Respuesta

30

Capybara no es una solución específica de rieles por lo que no sabe nada sobre la lógica de renderizado de rieles.

Capybara está destinado específicamente para las pruebas de integración, que esencialmente se ejecuta pruebas desde el punto de vista de un usuario final que interactúa con un navegador. En estas pruebas, no debería afirmar plantillas porque un usuario final no puede ver eso en lo más profundo de su aplicación. Lo que deberías probar es que una acción te lleva al camino correcto.

current_path.should == new_user_path 
page.should have_selector('div#erro_div') 
+1

Con las versiones más nuevas de Capybara esto ya no funciona. Tengo 2.10.1 y hay un nuevo método 'have_current_path' que se puede usar:' expect (page) .to have_current_path (new_user_path) ' – bjnord

11

El mensaje de error @request must be an ActionDispatch::Request le dice que rspec-carriles matcher redirect_to (delega a Rails assert_redirected_to) espera que sea utilizado en Rails pruebas funcionales (debe mezclarse en ActionController::TestCase). El código que publicó parece especificación de solicitud rspec-rails. Por lo tanto, redirect_to no está disponible.

La comprobación de la redirección no es compatible con las especificaciones de solicitud rspec-rails, pero es compatible con las pruebas de integración de Rails.

Si usted debe comprobar explícitamente cómo se realizó el redireccionamiento (que era una respuesta 301 y no una respuesta 307 y no algún javascript) es completamente suya.

+1

Gracias por explicarme esto. – Mohamad

10

que puede hacerlo de esta manera:

expect(current_path).to eql(new_app_user_registration_path) 
3

Aquí es solución hacker que encontré

# spec/features/user_confirmation_feature.rb 

feature 'User confirmation' do 
    scenario 'provide confirmation and redirect' do 
    visit "https://stackoverflow.com/users/123/confirm" 

    expect(page).to have_content('Please enter the confirmation code') 
    find("input[id$='confirmation_code']").set '1234' 

    do_not_follow_redirect do 
     click_button('Verify') 
     expect(page.driver.status_code).to eq(302) 
     expect(page.driver.browser.last_response['Location']).to match(/\/en\//[^\/]+\/edit$/) 
    end 
    end 

    protected 

    # Capybara won't follow redirects 
    def do_not_follow_redirect &block 
    begin 
     options = page.driver.instance_variable_get(:@options) 
     prev_value = options[:follow_redirects] 
     options[:follow_redirects] = false 

     yield 
    ensure 
     options[:follow_redirects] = prev_value 
    end 
    end 
end 
+0

Esto ayuda si su redireccionamiento es un enlace externo –

2

Rspec 3:

La forma más fácil de detectar la trayectoria de la corriente es con :

expect(page).to have_current_path('/login?status=invalid_token')

El have_current_path tiene una ventaja sobre este enfoque:

expect(current_path).to eq('/login')

porque se puede incluir Parámetros de consulta.

+1

que es la diferencia con espera (current_path) .to eq ('/ login? Status = invalid_token')? – sekmo

Cuestiones relacionadas