2014-10-20 21 views
6

In Rails 4.1.6, si verificano errori InvalidAuthenticityToken durante l'esecuzione dei test generati con lo scaffold. C'è un modo per disabilitare il controllo del token di autenticità per un test specifico?Test impalcatura non riusciti con ActionController :: InvalidAuthenticityToken

rails g scaffold user name:string email:string password_digest:string 
rake 

uscita:

... 

    1) Error: 
UsersControllerTest#test_should_create_user: 
ActionController::InvalidAuthenticityToken: ActionController::InvalidAuthenticityToken 
    test/controllers/users_controller_test.rb:21:in `block (2 levels) in <class:UsersControllerTest>' 
    test/controllers/users_controller_test.rb:20:in `block in <class:UsersControllerTest>' 

... 

Questo è il codice sorgente:

test "should create admin_user" do 
    assert_difference('Admin::User.count') do 
    post :create, admin_user: { email: @admin_user.email, password_digest: @admin_user.password_digest, username: @admin_user.username } 
    end 

    assert_redirected_to admin_user_path(assigns(:admin_user)) 
end 

risposta

8

ci sono alcune opzioni:

-> È possibile modificare il comportamento di rilevare CSRF invalid token per sessione di ripristino (come in Rails 3):

In application_controller.rb

protect_from_forgery with: :exception 

a

protect_from_forgery with: :null_session 

-> Si può fare con l'espressione condizionale, qualcosa di simile:

if Rails.env.test? 
    protect_from_forgery with: :null_session 
else 
    protect_from_forgery with: :exception 
end 

Tuttavia, questo ti ha dato una diversa configurazione po 'per il test e per dev/production env.

-> È possibile fornire l'autenticità di token manualmente nei test:

def set_form_authenticity_token 
    session[:_csrf_token] = SecureRandom.base64(32) 
end 

Ed in particolare test:

post :create, admin_user: { email: @admin_user.email, password_digest: @admin_user.password_digest, username: @admin_user.username }, authenticity_token: set_form_authenticity_token 

-> È possibile scrivere il proprio aiuto, qualcosa di simile:

def set_form_authenticity_token 
    session[:_csrf_token] = SecureRandom.base64(32) 
end 

alias_method :post_without_token, :post 
def post_with_token(symbol, args_hash) 
    args_hash.merge!(authenticity_token: set_form_authenticity_token) 
    post_without_token(symbol, args_hash) 
end 
alias_method :post, :post_with_token 
+0

Non ho potuto ottenere 'form_authenticity_token' per funzionare, suppongo perché è un metodo protetto. Sono stato in grado di superare il test impostando 'session [: _ csrf_token]' direttamente con 'SecureRandom.base64 (32)' (questo è ciò che 'form_authenticity_token' fa) e passando lo stesso valore del parametro' authenticity_token' nei dati del post . Sembra hackish, ma non sono sicuro di cos'altro fare. Grazie per la risposta. – Schrute

+1

Ho modificato la mia risposta - ora dovrebbe funzionare e non sembra tale hack;) – Esse

+0

il default di args_hash sarebbe utile '' def post_with_token (symbol, args_hash = {}) '' –

Problemi correlati