2014-10-20 77 views
6

在Rails 4.1.6中,運行使用腳手架生成的測試時出現InvalidAuthenticityToken錯誤。有什麼辦法可以禁用特定測試的真實性標記檢查嗎?腳手架測試失敗,ActionController :: InvalidAuthenticityToken

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

輸出:

... 

    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>' 

... 

這是源代碼:

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 

回答

8

有一些選項:

- >您可以更改檢測CSRF無效令牌行爲重置會話(就像它在Rails 3中):

application_controller.rb

protect_from_forgery with: :exception 

protect_from_forgery with: :null_session 

- >你可以做到這一點的條件表達式,是這樣的:

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

然而,這給了你一點點不同的配置測試和dev/production env。

- >您可以標記手動測試提供真僞:

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

,特別是測試:

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

- >您可以編寫自己的助手,是這樣的:

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

我無法讓'form_authenticity_token'工作,我猜是因爲它是一種受保護的方法。我可以直接用'SecureRandom.base64(32)'(這是'form_authenticity_token'的做法)設置'session [:_ csrf_token]'來通過測試,並在post數據中傳遞和'authenticity_token'參數相同的值。看起來很駭人,但我不知道還有什麼要做。感謝回覆。 – Schrute 2014-10-20 19:40:13

+1

我已經編輯了我的答案 - 現在它應該可以工作,並且看起來似乎不那麼討厭;) – Esse 2014-10-20 20:20:38

+0

默認args_hash會有幫助 def post_with_token(symbol,args_hash = {})'' – 2015-02-13 23:29:36

相關問題