2012-06-08 14 views
17

Non so cosa sto facendo male, ma ogni volta che provo a testare un reindirizzamento, ottengo questo errore: "@request deve essere un ActionDispatch :: richiesta"Come testare un reindirizzamento con Rspec e 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)>' 

sto utilizzando RSpec-rotaie (2.9.0) con Capybara (1.1.2) e Rails 3.2. Lo apprezzerei se qualcuno potesse anche spiegare perché questo sta accadendo; perché non posso usare l'aspettativa in questo modo?

+0

Forse mi manca qualcosa, ma cosa c'è di sbagliato in "assert_redirected_to'? –

+0

@JosephWeissman, ho lo stesso errore! – Mohamad

risposta

30

Capybara non è una soluzione specifica per binari quindi non conosce nulla sulla logica di rendering delle rotaie.

Capybara è specifico per i test di integrazione, che essenzialmente esegue test dal punto di vista di un utente finale che interagisce con un browser. In questi test, non dovresti affermare i modelli perché un utente finale non può vedere così a fondo nella tua applicazione. Quello che dovresti invece provare è che un'azione ti atterra sul percorso corretto.

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

Con le versioni più recenti di Capybara questo non funziona più. Ho 2.10.1 e c'è un nuovo metodo 'have_current_path' che può essere usato:' expect (page) .to have_current_path (new_user_path) ' – bjnord

11

Il messaggio di errore @request must be an ActionDispatch::Request si dice che RSpec-rails Matcher redirect_to (delega a Rails assert_redirected_to) si aspetta di essere utilizzato in Rails test funzionali (dovrebbe mescolare in ActionController::TestCase). Il codice che hai postato assomiglia alle specifiche di richiesta di rspec-rails. Quindi redirect_to non è disponibile.

Il controllo del reindirizzamento non è supportato nelle specifiche di richiesta rspec-rails, ma è supportato nei test di integrazione di Rails.

Se è necessario verificare esplicitamente la modalità di reindirizzamento (che è stata una risposta 301 e non una risposta 307 e non un javascript) dipende interamente da voi.

+1

Grazie per aver spiegato questo. – Mohamad

10

si può fare in questo modo:

expect(current_path).to eql(new_app_user_registration_path) 
3

Ecco soluzione hacker che ho trovato

# 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

Questo aiuta se il reindirizzamento sembra essere un collegamento esterno –

2

Rspec 3:

Il modo più semplice per verificare il percorso corrente è con :

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

Il have_current_path ha un vantaggio rispetto questo approccio:

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

perché è possibile includere parametri di query.

+1

che è la differenza con expect (current_path) .to eq ('/ login? Status = invalid_token')? – sekmo

Problemi correlati